2017-09-19 10:42:09 +00:00
|
|
|
#!/usr/bin/env python2
|
2017-02-01 16:48:41 +00:00
|
|
|
|
2018-01-05 13:35:42 +00:00
|
|
|
import os
|
2017-02-01 16:48:41 +00:00
|
|
|
import sys
|
|
|
|
import json
|
2017-03-16 11:25:30 +00:00
|
|
|
import xmltodict
|
2017-02-01 16:48:41 +00:00
|
|
|
|
|
|
|
# This is a list of x86 CPU features as of QEMU 2.8.50 and it won't need any
|
|
|
|
# updates since in the future because query-cpu-model-expansion will be used
|
|
|
|
# with newer QEMU.
|
|
|
|
cpuidMap = [
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000001, "edx": 0, "names": ["pni", "sse3"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000002, "edx": 0, "names": ["pclmulqdq", "pclmuldq"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000004, "edx": 0, "names": ["dtes64"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000008, "edx": 0, "names": ["monitor"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000010, "edx": 0, "names": ["ds-cpl", "ds_cpl"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000020, "edx": 0, "names": ["vmx"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000040, "edx": 0, "names": ["smx"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000080, "edx": 0, "names": ["est"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000100, "edx": 0, "names": ["tm2"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000200, "edx": 0, "names": ["ssse3"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000400, "edx": 0, "names": ["cid"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00001000, "edx": 0, "names": ["fma"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00002000, "edx": 0, "names": ["cx16"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00004000, "edx": 0, "names": ["xtpr"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00008000, "edx": 0, "names": ["pdcm"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00020000, "edx": 0, "names": ["pcid"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00040000, "edx": 0, "names": ["dca"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00080000, "edx": 0, "names": ["sse4.1", "sse4-1", "sse4_1"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00100000, "edx": 0, "names": ["sse4.2", "sse4-2", "sse4_2"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00200000, "edx": 0, "names": ["x2apic"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00400000, "edx": 0, "names": ["movbe"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00800000, "edx": 0, "names": ["popcnt"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x01000000, "edx": 0, "names": ["tsc-deadline"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x02000000, "edx": 0, "names": ["aes"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x04000000, "edx": 0, "names": ["xsave"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x08000000, "edx": 0, "names": ["osxsave"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x10000000, "edx": 0, "names": ["avx"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x20000000, "edx": 0, "names": ["f16c"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x40000000, "edx": 0, "names": ["rdrand"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x80000000, "edx": 0, "names": ["hypervisor"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000001, "names": ["fpu"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000002, "names": ["vme"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000004, "names": ["de"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000008, "names": ["pse"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000010, "names": ["tsc"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000020, "names": ["msr"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000040, "names": ["pae"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000080, "names": ["mce"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000100, "names": ["cx8"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000200, "names": ["apic"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000800, "names": ["sep"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00001000, "names": ["mtrr"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00002000, "names": ["pge"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00004000, "names": ["mca"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00008000, "names": ["cmov"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00010000, "names": ["pat"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00020000, "names": ["pse36"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00040000, "names": ["pn"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00080000, "names": ["clflush"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00200000, "names": ["ds"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00400000, "names": ["acpi"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00800000, "names": ["mmx"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x01000000, "names": ["fxsr"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x02000000, "names": ["sse"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x04000000, "names": ["sse2"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x08000000, "names": ["ss"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x10000000, "names": ["ht"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x20000000, "names": ["tm"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x40000000, "names": ["ia64"]},
|
|
|
|
{"in_eax": 0x00000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x80000000, "names": ["pbe"]},
|
|
|
|
{"in_eax": 0x00000006, "in_ecx": 0, "eax": 0x00000004, "ebx": 0, "ecx": 0, "edx": 0, "names": ["arat"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000001, "ecx": 0, "edx": 0, "names": ["fsgsbase"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000002, "ecx": 0, "edx": 0, "names": ["tsc-adjust", "tsc_adjust"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000008, "ecx": 0, "edx": 0, "names": ["bmi1"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000010, "ecx": 0, "edx": 0, "names": ["hle"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000020, "ecx": 0, "edx": 0, "names": ["avx2"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000080, "ecx": 0, "edx": 0, "names": ["smep"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000100, "ecx": 0, "edx": 0, "names": ["bmi2"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000200, "ecx": 0, "edx": 0, "names": ["erms"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000400, "ecx": 0, "edx": 0, "names": ["invpcid"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00000800, "ecx": 0, "edx": 0, "names": ["rtm"]},
|
2017-03-17 10:46:19 +00:00
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00001000, "ecx": 0, "edx": 0, "names": []}, # cmt is unknown to QEMU
|
2017-02-01 16:48:41 +00:00
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00004000, "ecx": 0, "edx": 0, "names": ["mpx"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00010000, "ecx": 0, "edx": 0, "names": ["avx512f"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00020000, "ecx": 0, "edx": 0, "names": ["avx512dq"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00040000, "ecx": 0, "edx": 0, "names": ["rdseed"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00080000, "ecx": 0, "edx": 0, "names": ["adx"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00100000, "ecx": 0, "edx": 0, "names": ["smap"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00200000, "ecx": 0, "edx": 0, "names": ["avx512ifma"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00400000, "ecx": 0, "edx": 0, "names": ["pcommit"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x00800000, "ecx": 0, "edx": 0, "names": ["clflushopt"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x01000000, "ecx": 0, "edx": 0, "names": ["clwb"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x04000000, "ecx": 0, "edx": 0, "names": ["avx512pf"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x08000000, "ecx": 0, "edx": 0, "names": ["avx512er"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x10000000, "ecx": 0, "edx": 0, "names": ["avx512cd"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x20000000, "ecx": 0, "edx": 0, "names": ["sha-ni"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x40000000, "ecx": 0, "edx": 0, "names": ["avx512bw"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0x80000000, "ecx": 0, "edx": 0, "names": ["avx512vl"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000002, "edx": 0, "names": ["avx512vbmi"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000004, "edx": 0, "names": ["umip"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000008, "edx": 0, "names": ["pku"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000010, "edx": 0, "names": ["ospke"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00004000, "edx": 0, "names": ["avx512-vpopcntdq"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00010000, "edx": 0, "names": ["la57"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00400000, "edx": 0, "names": ["rdpid"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000004, "names": ["avx512-4vnniw"]},
|
|
|
|
{"in_eax": 0x00000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000008, "names": ["avx512-4fmaps"]},
|
|
|
|
{"in_eax": 0x0000000d, "in_ecx": 1, "eax": 0x00000001, "ebx": 0, "ecx": 0, "edx": 0, "names": ["xsaveopt"]},
|
|
|
|
{"in_eax": 0x0000000d, "in_ecx": 1, "eax": 0x00000002, "ebx": 0, "ecx": 0, "edx": 0, "names": ["xsavec"]},
|
|
|
|
{"in_eax": 0x0000000d, "in_ecx": 1, "eax": 0x00000004, "ebx": 0, "ecx": 0, "edx": 0, "names": ["xgetbv1"]},
|
|
|
|
{"in_eax": 0x0000000d, "in_ecx": 1, "eax": 0x00000008, "ebx": 0, "ecx": 0, "edx": 0, "names": ["xsaves"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x00000001, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvmclock"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x00000002, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvm-nopiodelay", "kvm_nopiodelay"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x00000004, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvm-mmu", "kvm_mmu"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x00000008, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvmclock"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x00000010, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvm-asyncpf", "kvm_asyncpf"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x00000020, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvm-steal-time", "kvm_steal_time"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x00000040, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvm-pv-eoi", "kvm_pv_eoi"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x00000080, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvm-pv-unhalt", "kvm_pv_unhalt"]},
|
|
|
|
{"in_eax": 0x40000001, "in_ecx": 0, "eax": 0x01000000, "ebx": 0, "ecx": 0, "edx": 0, "names": ["kvmclock-stable-bit"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000001, "edx": 0, "names": ["lahf-lm", "lahf_lm"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000002, "edx": 0, "names": ["cmp-legacy", "cmp_legacy"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000004, "edx": 0, "names": ["svm"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000008, "edx": 0, "names": ["extapic"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000010, "edx": 0, "names": ["cr8legacy"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000020, "edx": 0, "names": ["abm"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000040, "edx": 0, "names": ["sse4a"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000080, "edx": 0, "names": ["misalignsse"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000100, "edx": 0, "names": ["3dnowprefetch"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000200, "edx": 0, "names": ["osvw"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000400, "edx": 0, "names": ["ibs"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00000800, "edx": 0, "names": ["xop"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00001000, "edx": 0, "names": ["skinit"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00002000, "edx": 0, "names": ["wdt"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00008000, "edx": 0, "names": ["lwp"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00010000, "edx": 0, "names": ["fma4"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00020000, "edx": 0, "names": ["tce"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00080000, "edx": 0, "names": ["nodeid-msr", "nodeid_msr"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00200000, "edx": 0, "names": ["tbm"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00400000, "edx": 0, "names": ["topoext"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x00800000, "edx": 0, "names": ["perfctr-core", "perfctr_core"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0x01000000, "edx": 0, "names": ["perfctr-nb", "perfctr_nb"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000800, "names": ["syscall"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00100000, "names": ["nx", "xd"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00400000, "names": ["mmxext"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x02000000, "names": ["fxsr-opt", "ffxsr", "fxsr_opt"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x04000000, "names": ["pdpe1gb"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x08000000, "names": ["rdtscp"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x20000000, "names": ["lm", "i64"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x40000000, "names": ["3dnowext"]},
|
|
|
|
{"in_eax": 0x80000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x80000000, "names": ["3dnow"]},
|
|
|
|
{"in_eax": 0x80000007, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000100, "names": ["invtsc"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000001, "names": ["npt"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000002, "names": ["lbrv"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000004, "names": ["svm-lock", "svm_lock"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000008, "names": ["nrip-save", "nrip_save"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000010, "names": ["tsc-scale", "tsc_scale"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000020, "names": ["vmcb-clean", "vmcb_clean"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000040, "names": ["flushbyasid"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000080, "names": ["decodeassists"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000400, "names": ["pause-filter", "pause_filter"]},
|
|
|
|
{"in_eax": 0x8000000A, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00001000, "names": ["pfthreshold"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000004, "names": ["xstore"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000008, "names": ["xstore-en"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000040, "names": ["xcrypt"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000080, "names": ["xcrypt-en"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000100, "names": ["ace2"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000200, "names": ["ace2-en"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000400, "names": ["phe"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00000800, "names": ["phe-en"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00001000, "names": ["pmm"]},
|
|
|
|
{"in_eax": 0xC0000001, "in_ecx": 0, "eax": 0, "ebx": 0, "ecx": 0, "edx": 0x00002000, "names": ["pmm-en"]},
|
|
|
|
]
|
|
|
|
|
|
|
|
|
2017-03-15 13:21:48 +00:00
|
|
|
def cpuidIsSet(cpuid, feature):
|
|
|
|
in_eax = feature["in_eax"]
|
|
|
|
in_ecx = feature["in_ecx"]
|
|
|
|
eax = feature["eax"]
|
|
|
|
ebx = feature["ebx"]
|
|
|
|
ecx = feature["ecx"]
|
|
|
|
edx = feature["edx"]
|
|
|
|
|
|
|
|
if in_eax not in cpuid or in_ecx not in cpuid[in_eax]:
|
|
|
|
return False
|
|
|
|
else:
|
|
|
|
leaf = cpuid[in_eax][in_ecx]
|
|
|
|
return ((eax > 0 and leaf["eax"] & eax > 0) or
|
|
|
|
(ebx > 0 and leaf["ebx"] & ebx > 0) or
|
|
|
|
(ecx > 0 and leaf["ecx"] & ecx > 0) or
|
|
|
|
(edx > 0 and leaf["edx"] & edx > 0))
|
|
|
|
|
|
|
|
|
2017-03-15 13:29:30 +00:00
|
|
|
def cpuidLeaf(cpuid, in_eax, in_ecx):
|
|
|
|
if in_eax not in cpuid:
|
|
|
|
cpuid[in_eax] = {}
|
|
|
|
leaf = cpuid[in_eax]
|
|
|
|
|
|
|
|
if in_ecx not in leaf:
|
|
|
|
leaf[in_ecx] = {"eax": 0, "ebx": 0, "ecx": 0, "edx": 0}
|
|
|
|
leaf = leaf[in_ecx]
|
|
|
|
|
|
|
|
return leaf
|
|
|
|
|
|
|
|
|
2017-03-16 11:25:30 +00:00
|
|
|
def cpuidAdd(cpuid, feature):
|
|
|
|
leaf = cpuidLeaf(cpuid, feature["in_eax"], feature["in_ecx"])
|
|
|
|
for reg in ["eax", "ebx", "ecx", "edx"]:
|
|
|
|
leaf[reg] |= feature[reg]
|
|
|
|
|
|
|
|
|
2017-02-01 16:48:41 +00:00
|
|
|
def parseFeatureWords(path):
|
|
|
|
features = None
|
|
|
|
|
2017-03-15 12:09:21 +00:00
|
|
|
dec = json.JSONDecoder()
|
|
|
|
|
2017-02-01 16:48:41 +00:00
|
|
|
with open(path, "r") as f:
|
|
|
|
s = f.read()
|
|
|
|
|
|
|
|
props = {}
|
2017-09-26 19:08:37 +00:00
|
|
|
rest = []
|
|
|
|
chunk = 0
|
|
|
|
while s != "":
|
2017-02-01 16:48:41 +00:00
|
|
|
(data, pos) = dec.raw_decode(s)
|
2017-09-26 19:08:37 +00:00
|
|
|
if chunk == 0:
|
2017-02-01 16:48:41 +00:00
|
|
|
features = data["return"]
|
2017-09-26 19:08:37 +00:00
|
|
|
elif chunk < 5:
|
2017-02-01 16:48:41 +00:00
|
|
|
keys = ["family", "model", "stepping", "model-id"]
|
2017-09-26 19:08:37 +00:00
|
|
|
props[keys[chunk - 1]] = data["return"]
|
|
|
|
else:
|
|
|
|
rest.append(data)
|
2017-02-01 16:48:41 +00:00
|
|
|
|
|
|
|
while pos < len(s) and s[pos] != "{":
|
|
|
|
pos += 1
|
|
|
|
s = s[pos:]
|
2017-09-26 19:08:37 +00:00
|
|
|
chunk += 1
|
2017-02-01 16:48:41 +00:00
|
|
|
|
|
|
|
if props["model-id"].find("Intel") != -1:
|
|
|
|
props["vendor"] = "GenuineIntel"
|
|
|
|
elif props["model-id"].find("AMD") != -1:
|
|
|
|
props["vendor"] = "AuthenticAMD"
|
|
|
|
|
|
|
|
cpuid = {}
|
|
|
|
for feat in features:
|
|
|
|
in_eax = feat["cpuid-input-eax"]
|
|
|
|
in_ecx = 0
|
|
|
|
if "cpuid-input-ecx" in feat:
|
|
|
|
in_ecx = feat["cpuid-input-ecx"]
|
|
|
|
|
2017-03-15 13:29:30 +00:00
|
|
|
leaf = cpuidLeaf(cpuid, in_eax, in_ecx)
|
2017-02-01 16:48:41 +00:00
|
|
|
leaf[feat["cpuid-register"].lower()] = feat["features"]
|
|
|
|
|
2017-09-26 19:08:37 +00:00
|
|
|
return props, cpuid, rest
|
2017-02-01 16:48:41 +00:00
|
|
|
|
|
|
|
|
2017-03-16 11:25:30 +00:00
|
|
|
def parseQemu(path, features):
|
|
|
|
cpuid = {}
|
|
|
|
with open(path, "r") as f:
|
2017-09-26 19:08:37 +00:00
|
|
|
data, pos = json.JSONDecoder().raw_decode(f.read())
|
2017-03-16 11:25:30 +00:00
|
|
|
|
|
|
|
for (prop, val) in data["return"]["model"]["props"].iteritems():
|
|
|
|
if val and prop in features:
|
|
|
|
cpuidAdd(cpuid, features[prop])
|
|
|
|
|
|
|
|
return cpuid
|
|
|
|
|
|
|
|
|
|
|
|
def parseCpuid(path):
|
|
|
|
cpuid = {}
|
|
|
|
with open(path, "r") as f:
|
|
|
|
data = xmltodict.parse(f)
|
|
|
|
|
|
|
|
for leaf in data["cpudata"]["cpuid"]:
|
|
|
|
feature = {}
|
|
|
|
feature["in_eax"] = int(leaf["@eax_in"], 0)
|
|
|
|
feature["in_ecx"] = int(leaf["@ecx_in"], 0)
|
|
|
|
for reg in ["eax", "ebx", "ecx", "edx"]:
|
|
|
|
feature[reg] = int(leaf["@" + reg], 0)
|
|
|
|
|
|
|
|
cpuidAdd(cpuid, feature)
|
|
|
|
|
|
|
|
return cpuid
|
|
|
|
|
|
|
|
|
2018-01-05 13:35:42 +00:00
|
|
|
def parseFeature(data):
|
|
|
|
cpuid = {}
|
|
|
|
for reg in ["in_eax", "in_ecx", "eax", "ebx", "ecx", "edx"]:
|
|
|
|
if reg.startswith("in_"):
|
|
|
|
attr = "@%s_in" % reg[3:]
|
|
|
|
else:
|
|
|
|
attr = "@%s" % reg
|
|
|
|
|
|
|
|
if attr in data:
|
|
|
|
cpuid[reg] = int(data[attr], 0)
|
|
|
|
else:
|
|
|
|
cpuid[reg] = 0
|
|
|
|
|
|
|
|
return cpuid
|
|
|
|
|
|
|
|
|
|
|
|
def parseMap():
|
|
|
|
path = os.path.dirname(sys.argv[0])
|
2019-02-21 19:10:48 +00:00
|
|
|
path = os.path.join(path, "..", "..", "src", "cpu_map", "x86_features.xml")
|
2018-01-05 13:35:42 +00:00
|
|
|
with open(path, "r") as f:
|
|
|
|
data = xmltodict.parse(f)
|
|
|
|
|
|
|
|
cpuMap = {}
|
2019-02-21 19:10:48 +00:00
|
|
|
for feature in data["cpus"]["feature"]:
|
|
|
|
cpuMap[feature["@name"]] = parseFeature(feature["cpuid"])
|
2018-01-05 13:35:42 +00:00
|
|
|
|
|
|
|
return cpuMap
|
|
|
|
|
|
|
|
|
2017-03-16 11:25:30 +00:00
|
|
|
def formatCpuid(cpuid, path, comment):
|
2017-09-26 19:08:37 +00:00
|
|
|
print path
|
2017-03-16 11:25:30 +00:00
|
|
|
with open(path, "w") as f:
|
|
|
|
f.write("<!-- " + comment + " -->\n")
|
|
|
|
f.write("<cpudata arch='x86'>\n")
|
|
|
|
for in_eax in sorted(cpuid.keys()):
|
|
|
|
for in_ecx in sorted(cpuid[in_eax].keys()):
|
|
|
|
leaf = cpuid[in_eax][in_ecx]
|
|
|
|
line = (" <cpuid eax_in='0x%08x' ecx_in='0x%02x' "
|
|
|
|
"eax='0x%08x' ebx='0x%08x' "
|
|
|
|
"ecx='0x%08x' edx='0x%08x'/>\n")
|
2018-03-20 06:48:47 +00:00
|
|
|
f.write(line % (
|
2017-03-16 11:25:30 +00:00
|
|
|
in_eax, in_ecx,
|
|
|
|
leaf["eax"], leaf["ebx"], leaf["ecx"], leaf["edx"]))
|
|
|
|
f.write("</cpudata>\n")
|
|
|
|
|
|
|
|
|
2017-03-15 12:16:37 +00:00
|
|
|
def convert(path):
|
2017-09-26 19:08:37 +00:00
|
|
|
props, cpuid, rest = parseFeatureWords(path)
|
2017-02-01 16:48:41 +00:00
|
|
|
|
|
|
|
for feature in cpuidMap:
|
2017-03-15 13:21:48 +00:00
|
|
|
value = cpuidIsSet(cpuid, feature)
|
|
|
|
for name in feature["names"]:
|
|
|
|
props[name] = value
|
2017-02-01 16:48:41 +00:00
|
|
|
|
2017-09-26 19:08:37 +00:00
|
|
|
print path
|
2017-02-01 16:48:41 +00:00
|
|
|
with open(path, "w") as f:
|
|
|
|
json.dump({"return": {"model": {"name": "base", "props": props}},
|
|
|
|
"id": "model-expansion"},
|
2018-03-20 06:48:54 +00:00
|
|
|
f, indent=2, separators=(',', ': '))
|
2017-02-01 16:48:41 +00:00
|
|
|
f.write("\n")
|
2017-09-26 19:08:37 +00:00
|
|
|
|
|
|
|
for chunk in rest:
|
|
|
|
f.write("\n")
|
2018-03-20 06:48:54 +00:00
|
|
|
json.dump(chunk, f, indent=2, separators=(',', ': '))
|
2017-09-26 19:08:37 +00:00
|
|
|
f.write("\n")
|
2017-03-15 12:16:37 +00:00
|
|
|
|
|
|
|
|
2018-01-05 13:35:42 +00:00
|
|
|
def diff(cpuMap, path):
|
2017-03-16 11:25:30 +00:00
|
|
|
base = path.replace(".json", "")
|
|
|
|
jsonFile = path
|
|
|
|
cpuidFile = base + ".xml"
|
|
|
|
enabledFile = base + "-enabled.xml"
|
|
|
|
disabledFile = base + "-disabled.xml"
|
|
|
|
|
|
|
|
cpuid = parseCpuid(cpuidFile)
|
2018-01-05 13:35:42 +00:00
|
|
|
qemu = parseQemu(jsonFile, cpuMap)
|
2017-03-16 11:25:30 +00:00
|
|
|
|
|
|
|
enabled = {}
|
|
|
|
disabled = {}
|
2018-01-05 13:35:42 +00:00
|
|
|
for feature in cpuMap.values():
|
2017-03-16 11:25:30 +00:00
|
|
|
if cpuidIsSet(qemu, feature):
|
|
|
|
cpuidAdd(enabled, feature)
|
|
|
|
elif cpuidIsSet(cpuid, feature):
|
|
|
|
cpuidAdd(disabled, feature)
|
|
|
|
|
|
|
|
formatCpuid(enabled, enabledFile, "Features enabled by QEMU")
|
|
|
|
formatCpuid(disabled, disabledFile, "Features disabled by QEMU")
|
|
|
|
|
|
|
|
|
2017-03-15 12:16:37 +00:00
|
|
|
if len(sys.argv) < 3:
|
2017-03-16 11:25:30 +00:00
|
|
|
print "Usage: %s convert|diff json_file..." % sys.argv[0]
|
2017-03-15 12:16:37 +00:00
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
action = sys.argv[1]
|
|
|
|
args = sys.argv[2:]
|
|
|
|
|
|
|
|
if action == "convert":
|
|
|
|
for path in args:
|
|
|
|
convert(path)
|
2017-03-16 11:25:30 +00:00
|
|
|
elif action == "diff":
|
2018-01-05 13:35:42 +00:00
|
|
|
cpuMap = parseMap()
|
2017-03-16 11:25:30 +00:00
|
|
|
for path in args:
|
2018-01-05 13:35:42 +00:00
|
|
|
diff(cpuMap, path)
|
2017-03-15 12:16:37 +00:00
|
|
|
else:
|
|
|
|
print "Unknown action: " + action
|
|
|
|
sys.exit(1)
|