test_cpuid_x64.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Hypervisor
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 #include <test.h>
23 #include <intrinsics/cpuid_x64.h>
24 
25 using namespace x64;
26 
27 std::map<cpuid::field_type, cpuid::value_type> g_eax_cpuid;
28 std::map<cpuid::field_type, cpuid::value_type> g_ebx_cpuid;
29 std::map<cpuid::field_type, cpuid::value_type> g_ecx_cpuid;
30 std::map<cpuid::field_type, cpuid::value_type> g_edx_cpuid;
31 
32 extern "C" uint32_t __cpuid_eax(uint32_t val) noexcept;
33 extern "C" uint32_t __cpuid_ebx(uint32_t val) noexcept;
34 extern "C" uint32_t __cpuid_ecx(uint32_t val) noexcept;
35 extern "C" uint32_t __cpuid_edx(uint32_t val) noexcept;
36 extern "C" void __cpuid(void *eax, void *ebx, void *ecx, void *edx) noexcept;
37 
38 struct cpuid_regs
39 {
44 };
45 
46 struct cpuid_regs g_regs;
47 
48 extern "C" uint32_t
49 __cpuid_eax(uint32_t val) noexcept
50 { return g_eax_cpuid[val]; }
51 
52 extern "C" uint32_t
53 __cpuid_ebx(uint32_t val) noexcept
54 { return g_ebx_cpuid[val]; }
55 
56 extern "C" uint32_t
57 __cpuid_ecx(uint32_t val) noexcept
58 { return g_ecx_cpuid[val]; }
59 
60 extern "C" uint32_t
61 __cpuid_edx(uint32_t val) noexcept
62 { return g_edx_cpuid[val]; }
63 
64 extern "C" void
65 __cpuid(void *eax, void *ebx, void *ecx, void *edx) noexcept
66 {
67  *static_cast<cpuid::value_type *>(eax) = g_regs.eax;
68  *static_cast<cpuid::value_type *>(ebx) = g_regs.ebx;
69  *static_cast<cpuid::value_type *>(ecx) = g_regs.ecx;
70  *static_cast<cpuid::value_type *>(edx) = g_regs.edx;
71 }
72 
73 void
74 intrinsics_ut::test_cpuid_x64_cpuid()
75 {
76  g_regs.eax = 1U;
77  g_regs.ebx = 2U;
78  g_regs.ecx = 3U;
79  g_regs.edx = 4U;
80 
81  auto ret = cpuid::get(g_regs.eax, g_regs.ebx, g_regs.ecx, g_regs.edx);
82 
83  this->expect_true(std::get<0>(ret) == 1U);
84  this->expect_true(std::get<1>(ret) == 2U);
85  this->expect_true(std::get<2>(ret) == 3U);
86  this->expect_true(std::get<3>(ret) == 4U);
87 }
88 
89 void
90 intrinsics_ut::test_cpuid_x64_cpuid_eax()
91 {
92  g_eax_cpuid[10U] = 42U;
93  this->expect_true(cpuid::eax::get(10U) == 42U);
94  this->expect_true(cpuid::eax::get(10UL) == 42U);
95 }
96 
97 void
98 intrinsics_ut::test_cpuid_x64_cpuid_ebx()
99 {
100  g_ebx_cpuid[10U] = 42U;
101  this->expect_true(cpuid::ebx::get(10U) == 42U);
102  this->expect_true(cpuid::ebx::get(10UL) == 42U);
103 }
104 
105 void
106 intrinsics_ut::test_cpuid_x64_cpuid_ecx()
107 {
108  g_ecx_cpuid[10U] = 42U;
109  this->expect_true(cpuid::ecx::get(10U) == 42U);
110  this->expect_true(cpuid::ecx::get(10UL) == 42U);
111 }
112 
113 void
114 intrinsics_ut::test_cpuid_x64_cpuid_edx()
115 {
116  g_edx_cpuid[10U] = 42U;
117  this->expect_true(cpuid::edx::get(10U) == 42U);
118  this->expect_true(cpuid::edx::get(10UL) == 42U);
119 }
120 
121 void
122 intrinsics_ut::test_cpuid_x64_cpuid_addr_size_phys()
123 {
124  g_eax_cpuid[cpuid::addr_size::addr] = 0x12345610;
125  this->expect_true(cpuid::addr_size::phys::get() == 0x10);
126 }
127 
128 void
129 intrinsics_ut::test_cpuid_x64_cpuid_addr_size_linear()
130 {
131  g_eax_cpuid[cpuid::addr_size::addr] = 0x12341056;
133 }
134 
135 void
136 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_sse3()
137 {
140 
143 }
144 
145 void
146 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_pclmulqdq()
147 {
150 
153 }
154 
155 void
156 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_dtes64()
157 {
160 
163 }
164 
165 void
166 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_monitor()
167 {
170 
173 }
174 
175 void
176 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_ds_cpl()
177 {
180 
183 }
184 
185 void
186 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_vmx()
187 {
190 
193 }
194 
195 void
196 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_smx()
197 {
200 
203 }
204 
205 void
206 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_eist()
207 {
210 
213 }
214 
215 void
216 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_tm2()
217 {
220 
223 }
224 
225 void
226 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_ssse3()
227 {
230 
233 }
234 
235 void
236 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_cnxt_id()
237 {
240 
243 }
244 
245 void
246 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_sdbg()
247 {
250 
253 }
254 
255 void
256 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_fma()
257 {
260 
263 }
264 
265 void
266 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_cmpxchg16b()
267 {
270 
273 }
274 
275 void
276 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_xtpr_update_control()
277 {
280 
283 }
284 
285 void
286 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_pdcm()
287 {
290 
293 }
294 
295 void
296 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_pcid()
297 {
300 
303 }
304 
305 void
306 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_dca()
307 {
310 
313 }
314 
315 void
316 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_sse41()
317 {
320 
323 }
324 
325 void
326 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_sse42()
327 {
330 
333 }
334 
335 void
336 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_x2apic()
337 {
340 
343 }
344 
345 void
346 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_movbe()
347 {
350 
353 }
354 
355 void
356 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_popcnt()
357 {
360 
363 }
364 
365 void
366 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_tsc_deadline()
367 {
370 
373 }
374 
375 void
376 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_aesni()
377 {
380 
383 }
384 
385 void
386 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_xsave()
387 {
390 
393 }
394 
395 void
396 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_osxsave()
397 {
400 
403 }
404 
405 void
406 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_avx()
407 {
410 
413 }
414 
415 void
416 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_f16c()
417 {
420 
423 }
424 
425 void
426 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_rdrand()
427 {
430 
433 }
434 
435 void
436 intrinsics_ut::test_cpuid_x64_cpuid_feature_information_ecx_dump()
437 {
440 }
441 
442 void
443 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_fsgsbase()
444 {
445  g_regs.ebx = 0x1U << 0;
447 
448  g_regs.ebx = ~(0x1U << 0);
450 }
451 
452 void
453 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_ia32_tsc_adjust()
454 {
455  g_regs.ebx = 0x1U << 1;
457 
458  g_regs.ebx = ~(0x1U << 1);
460 }
461 
462 void
463 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_sgx()
464 {
465  g_regs.ebx = 0x1U << 2;
467 
468  g_regs.ebx = ~(0x1U << 2);
470 }
471 
472 void
473 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_bmi1()
474 {
475  g_regs.ebx = 0x1U << 3;
477 
478  g_regs.ebx = ~(0x1U << 3);
480 }
481 
482 void
483 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_hle()
484 {
485  g_regs.ebx = 0x1U << 4;
487 
488  g_regs.ebx = ~(0x1U << 4);
490 }
491 
492 void
493 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_avx2()
494 {
495  g_regs.ebx = 0x1U << 5;
497 
498  g_regs.ebx = ~(0x1U << 5);
500 }
501 
502 void
503 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_fdp_excptn_only()
504 {
505  g_regs.ebx = 0x1U << 6;
507 
508  g_regs.ebx = ~(0x1U << 6);
510 }
511 
512 void
513 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_smep()
514 {
515  g_regs.ebx = 0x1U << 7;
517 
518  g_regs.ebx = ~(0x1U << 7);
520 }
521 
522 void
523 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_bmi2()
524 {
525  g_regs.ebx = 0x1U << 8;
527 
528  g_regs.ebx = ~(0x1U << 8);
530 }
531 
532 void
533 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_enhanced_rep()
534 {
535  g_regs.ebx = 0x1U << 9;
537 
538  g_regs.ebx = ~(0x1U << 9);
540 }
541 
542 void
543 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_invpcid()
544 {
545  g_regs.ebx = 0x1U << 10;
547 
548  g_regs.ebx = ~(0x1U << 10);
550 }
551 
552 void
553 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_rtm()
554 {
555  g_regs.ebx = 0x1U << 11;
557 
558  g_regs.ebx = ~(0x1U << 11);
560 }
561 
562 void
563 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_rdt_m()
564 {
565  g_regs.ebx = 0x1U << 12;
567 
568  g_regs.ebx = ~(0x1U << 12);
570 }
571 
572 void
573 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_depreciated_fpu_cs_ds()
574 {
575  g_regs.ebx = 0x1U << 13;
577 
578  g_regs.ebx = ~(0x1U << 13);
580 }
581 
582 void
583 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_mpx()
584 {
585  g_regs.ebx = 0x1U << 14;
587 
588  g_regs.ebx = ~(0x1U << 14);
590 }
591 
592 void
593 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_rdt_a()
594 {
595  g_regs.ebx = 0x1U << 15;
597 
598  g_regs.ebx = ~(0x1U << 15);
600 }
601 
602 void
603 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_rdseed()
604 {
605  g_regs.ebx = 0x1U << 18;
607 
608  g_regs.ebx = ~(0x1U << 18);
610 }
611 
612 void
613 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_adx()
614 {
615  g_regs.ebx = 0x1U << 19;
617 
618  g_regs.ebx = ~(0x1U << 19);
620 }
621 
622 void
623 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_smap()
624 {
625  g_regs.ebx = 0x1U << 20;
627 
628  g_regs.ebx = ~(0x1U << 20);
630 }
631 
632 void
633 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_clflushopt()
634 {
635  g_regs.ebx = 0x1U << 23;
637 
638  g_regs.ebx = ~(0x1U << 23);
640 }
641 
642 void
643 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_clwb()
644 {
645  g_regs.ebx = 0x1U << 24;
647 
648  g_regs.ebx = ~(0x1U << 24);
650 }
651 
652 void
653 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_processor_trace()
654 {
655  g_regs.ebx = 0x1U << 25;
657 
658  g_regs.ebx = ~(0x1U << 25);
660 }
661 
662 void
663 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_sha()
664 {
665  g_regs.ebx = 0x1U << 29;
667 
668  g_regs.ebx = ~(0x1U << 29);
670 }
671 
672 void
673 intrinsics_ut::test_cpuid_x64_cpuid_extended_feature_flags_subleaf0_ebx_dump()
674 {
675  g_regs.ebx = 0xFFFFFFFFU;
677 }
678 
679 void
680 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_eax_version_id()
681 {
682  g_eax_cpuid[0xA] = 2;
684 }
685 
686 void
687 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_eax_gppmc_count()
688 {
689  g_eax_cpuid[0xA] = 0xFF02;
691 }
692 
693 void
694 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_eax_gppmc_bit_width()
695 {
696  g_eax_cpuid[0xA] = 0xFF0002;
698 }
699 
700 void
701 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_eax_ebx_enumeration_length()
702 {
703  g_eax_cpuid[0xA] = 0xFF000000;
705 }
706 
707 void
708 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_ebx_core_cycle_event()
709 {
710  g_ebx_cpuid[0xA] = 0x1U;
712 
713  g_ebx_cpuid[0xA] = ~0x1U;
715 }
716 
717 void
718 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_ebx_instr_retired_event()
719 {
720  g_ebx_cpuid[0xA] = 0x2U;
722 
723  g_ebx_cpuid[0xA] = ~0x2U;
725 }
726 
727 void
728 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_ebx_reference_cycles_event()
729 {
730  g_ebx_cpuid[0xA] = 0x4U;
732 
733  g_ebx_cpuid[0xA] = ~0x4U;
735 }
736 
737 void
738 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_ebx_llc_reference_event()
739 {
740  g_ebx_cpuid[0xA] = 0x8U;
742 
743  g_ebx_cpuid[0xA] = ~0x8U;
745 }
746 
747 void
748 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_ebx_llc_misses_event()
749 {
750  g_ebx_cpuid[0xA] = 0x10U;
752 
753  g_ebx_cpuid[0xA] = ~0x10U;
755 }
756 
757 void
758 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_ebx_branch_instr_retired_event()
759 {
760  g_ebx_cpuid[0xA] = 0x20U;
762 
763  g_ebx_cpuid[0xA] = ~0x20U;
765 }
766 
767 void
768 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_ebx_branch_mispredict_retired_event()
769 {
770  g_ebx_cpuid[0xA] = 0x40U;
772 
773  g_ebx_cpuid[0xA] = ~0x40U;
775 }
776 
777 void
778 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_edx_ffpmc_count()
779 {
780  g_edx_cpuid[0xA] = 2;
782 }
783 
784 void
785 intrinsics_ut::test_cpuid_x64_cpuid_arch_perf_monitoring_edx_ffpmc_bit_width()
786 {
787  g_edx_cpuid[0xA] = 0xE2;
789 }
uint32_t __cpuid_eax(uint32_t val) noexcept
uint32_t __cpuid_ecx(uint32_t val) noexcept
void __cpuid(void *eax, void *ebx, void *ecx, void *edx) noexcept
std::map< cpuid::field_type, cpuid::value_type > g_edx_cpuid
uint32_t value_type
Definition: cpuid_x64.h:41
auto get(T edx) noexcept
Definition: cpuid_x64.h:75
void uint64_t uint64_t uint64_t *rdx noexcept
struct cpuid_regs g_regs
constexpr const auto addr
Definition: cpuid_x64.h:80
std::map< cpuid::field_type, cpuid::value_type > g_eax_cpuid
std::map< cpuid::field_type, cpuid::value_type > g_ecx_cpuid
auto get(T eax) noexcept
Definition: cpuid_x64.h:57
auto get(T1 eax, T2 ebx, T3 ecx, T4 edx) noexcept
Definition: cpuid_x64.h:48
constexpr const auto addr
Definition: cpuid_x64.h:106
auto get(T ecx) noexcept
Definition: cpuid_x64.h:69
auto get() noexcept
Definition: cpuid_x64.h:89
uint32_t __cpuid_edx(uint32_t val) noexcept
auto get(T ebx) noexcept
Definition: cpuid_x64.h:63
std::map< cpuid::field_type, cpuid::value_type > g_ebx_cpuid
#define expect_false(a)
Definition: cache_x64.h:31
#define expect_true(a)
uint32_t __cpuid_ebx(uint32_t val) noexcept