15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2011 by Delphix. All rights reserved.
24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2014 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
26 */
27 /*
28 * Copyright (c) 2010, Intel Corporation.
29 * All rights reserved.
30 */
31 /*
32 * Portions Copyright 2009 Advanced Micro Devices, Inc.
33 */
34 /*
35 * Copyright (c) 2015, Joyent, Inc. All rights reserved.
36 */
37 /*
38 * Various routines to handle identification
39 * and classification of x86 processors.
40 */
41
42 #include <sys/types.h>
43 #include <sys/archsystm.h>
44 #include <sys/x86_archext.h>
45 #include <sys/kmem.h>
46 #include <sys/systm.h>
47 #include <sys/cmn_err.h>
48 #include <sys/sunddi.h>
49 #include <sys/sunndi.h>
50 #include <sys/cpuvar.h>
51 #include <sys/processor.h>
52 #include <sys/sysmacros.h>
53 #include <sys/pg.h>
54 #include <sys/fp.h>
55 #include <sys/controlregs.h>
56 #include <sys/bitmap.h>
57 #include <sys/auxv_386.h>
58 #include <sys/memnode.h>
59 #include <sys/pci_cfgspace.h>
60
61 #ifdef __xpv
62 #include <sys/hypervisor.h>
63 #else
64 #include <sys/ontrap.h>
65 #endif
66
67 /*
68 * Pass 0 of cpuid feature analysis happens in locore. It contains special code
69 * to recognize Cyrix processors that are not cpuid-compliant, and to deal with
70 * them accordingly. For most modern processors, feature detection occurs here
71 * in pass 1.
72 *
73 * Pass 1 of cpuid feature analysis happens just at the beginning of mlsetup()
74 * for the boot CPU and does the basic analysis that the early kernel needs.
75 * x86_featureset is set based on the return value of cpuid_pass1() of the boot
76 * CPU.
77 *
78 * Pass 1 includes:
79 *
2809 hwcap_flags |= AV_386_MMX;
2810
2811 if (*edx & CPUID_INTC_EDX_TSC)
2812 hwcap_flags |= AV_386_TSC;
2813 if (*edx & CPUID_INTC_EDX_CX8)
2814 hwcap_flags |= AV_386_CX8;
2815 if (*edx & CPUID_INTC_EDX_CMOV)
2816 hwcap_flags |= AV_386_CMOV;
2817 if (*ecx & CPUID_INTC_ECX_CX16)
2818 hwcap_flags |= AV_386_CX16;
2819
2820 if (*ecx & CPUID_INTC_ECX_RDRAND)
2821 hwcap_flags_2 |= AV_386_2_RDRAND;
2822 if (*ebx & CPUID_INTC_EBX_7_0_ADX)
2823 hwcap_flags_2 |= AV_386_2_ADX;
2824 if (*ebx & CPUID_INTC_EBX_7_0_RDSEED)
2825 hwcap_flags_2 |= AV_386_2_RDSEED;
2826
2827 }
2828
2829 if (cpi->cpi_xmaxeax < 0x80000001)
2830 goto pass4_done;
2831
2832 switch (cpi->cpi_vendor) {
2833 struct cpuid_regs cp;
2834 uint32_t *edx, *ecx;
2835
2836 case X86_VENDOR_Intel:
2837 /*
2838 * Seems like Intel duplicated what we necessary
2839 * here to make the initial crop of 64-bit OS's work.
2840 * Hopefully, those are the only "extended" bits
2841 * they'll add.
2842 */
2843 /*FALLTHROUGH*/
2844
2845 case X86_VENDOR_AMD:
2846 edx = &cpi->cpi_support[AMD_EDX_FEATURES];
2847 ecx = &cpi->cpi_support[AMD_ECX_FEATURES];
2848
4590 if (cpu->cpu_m.mcpu_cpi == NULL) {
4591 return;
4592 }
4593
4594 if (cpu->cpu_m.mcpu_cpi->cpi_mwait.buf_actual != NULL &&
4595 cpu->cpu_m.mcpu_cpi->cpi_mwait.size_actual > 0) {
4596 kmem_free(cpu->cpu_m.mcpu_cpi->cpi_mwait.buf_actual,
4597 cpu->cpu_m.mcpu_cpi->cpi_mwait.size_actual);
4598 }
4599
4600 cpu->cpu_m.mcpu_cpi->cpi_mwait.buf_actual = NULL;
4601 cpu->cpu_m.mcpu_cpi->cpi_mwait.size_actual = 0;
4602 }
4603
4604 void
4605 patch_tsc_read(int flag)
4606 {
4607 size_t cnt;
4608
4609 switch (flag) {
4610 case X86_NO_TSC:
4611 cnt = &_no_rdtsc_end - &_no_rdtsc_start;
4612 (void) memcpy((void *)tsc_read, (void *)&_no_rdtsc_start, cnt);
4613 break;
4614 case X86_HAVE_TSCP:
4615 cnt = &_tscp_end - &_tscp_start;
4616 (void) memcpy((void *)tsc_read, (void *)&_tscp_start, cnt);
4617 break;
4618 case X86_TSC_MFENCE:
4619 cnt = &_tsc_mfence_end - &_tsc_mfence_start;
4620 (void) memcpy((void *)tsc_read,
4621 (void *)&_tsc_mfence_start, cnt);
4622 break;
4623 case X86_TSC_LFENCE:
4624 cnt = &_tsc_lfence_end - &_tsc_lfence_start;
4625 (void) memcpy((void *)tsc_read,
4626 (void *)&_tsc_lfence_start, cnt);
4627 break;
4628 default:
4629 break;
4630 }
4631 }
4632
4633 int
4634 cpuid_deep_cstates_supported(void)
4635 {
4636 struct cpuid_info *cpi;
4637 struct cpuid_regs regs;
4638
4639 ASSERT(cpuid_checkpass(CPU, 1));
4640
4641 cpi = CPU->cpu_m.mcpu_cpi;
4642
4643 if (!is_x86_feature(x86_featureset, X86FSET_CPUID))
4644 return (0);
4645
4646 switch (cpi->cpi_vendor) {
4647 case X86_VENDOR_Intel:
4648 if (cpi->cpi_xmaxeax < 0x80000007)
4649 return (0);
4650
|
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2011 by Delphix. All rights reserved.
24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2014 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
26 */
27 /*
28 * Copyright (c) 2010, Intel Corporation.
29 * All rights reserved.
30 */
31 /*
32 * Portions Copyright 2009 Advanced Micro Devices, Inc.
33 */
34 /*
35 * Copyright 2016 Joyent, Inc.
36 */
37 /*
38 * Various routines to handle identification
39 * and classification of x86 processors.
40 */
41
42 #include <sys/types.h>
43 #include <sys/archsystm.h>
44 #include <sys/x86_archext.h>
45 #include <sys/kmem.h>
46 #include <sys/systm.h>
47 #include <sys/cmn_err.h>
48 #include <sys/sunddi.h>
49 #include <sys/sunndi.h>
50 #include <sys/cpuvar.h>
51 #include <sys/processor.h>
52 #include <sys/sysmacros.h>
53 #include <sys/pg.h>
54 #include <sys/fp.h>
55 #include <sys/controlregs.h>
56 #include <sys/bitmap.h>
57 #include <sys/auxv_386.h>
58 #include <sys/memnode.h>
59 #include <sys/pci_cfgspace.h>
60 #include <sys/comm_page.h>
61 #include <sys/tsc.h>
62
63 #ifdef __xpv
64 #include <sys/hypervisor.h>
65 #else
66 #include <sys/ontrap.h>
67 #endif
68
69 /*
70 * Pass 0 of cpuid feature analysis happens in locore. It contains special code
71 * to recognize Cyrix processors that are not cpuid-compliant, and to deal with
72 * them accordingly. For most modern processors, feature detection occurs here
73 * in pass 1.
74 *
75 * Pass 1 of cpuid feature analysis happens just at the beginning of mlsetup()
76 * for the boot CPU and does the basic analysis that the early kernel needs.
77 * x86_featureset is set based on the return value of cpuid_pass1() of the boot
78 * CPU.
79 *
80 * Pass 1 includes:
81 *
2811 hwcap_flags |= AV_386_MMX;
2812
2813 if (*edx & CPUID_INTC_EDX_TSC)
2814 hwcap_flags |= AV_386_TSC;
2815 if (*edx & CPUID_INTC_EDX_CX8)
2816 hwcap_flags |= AV_386_CX8;
2817 if (*edx & CPUID_INTC_EDX_CMOV)
2818 hwcap_flags |= AV_386_CMOV;
2819 if (*ecx & CPUID_INTC_ECX_CX16)
2820 hwcap_flags |= AV_386_CX16;
2821
2822 if (*ecx & CPUID_INTC_ECX_RDRAND)
2823 hwcap_flags_2 |= AV_386_2_RDRAND;
2824 if (*ebx & CPUID_INTC_EBX_7_0_ADX)
2825 hwcap_flags_2 |= AV_386_2_ADX;
2826 if (*ebx & CPUID_INTC_EBX_7_0_RDSEED)
2827 hwcap_flags_2 |= AV_386_2_RDSEED;
2828
2829 }
2830
2831 /* Detect systems with a potential CPUID limit */
2832 if (cpi->cpi_vendor == X86_VENDOR_Intel && cpi->cpi_maxeax < 4) {
2833 cmn_err(CE_NOTE, "CPUID limit detected, "
2834 "see the CPUID(7D) man page for details\n");
2835 }
2836
2837
2838 if (cpi->cpi_xmaxeax < 0x80000001)
2839 goto pass4_done;
2840
2841 switch (cpi->cpi_vendor) {
2842 struct cpuid_regs cp;
2843 uint32_t *edx, *ecx;
2844
2845 case X86_VENDOR_Intel:
2846 /*
2847 * Seems like Intel duplicated what we necessary
2848 * here to make the initial crop of 64-bit OS's work.
2849 * Hopefully, those are the only "extended" bits
2850 * they'll add.
2851 */
2852 /*FALLTHROUGH*/
2853
2854 case X86_VENDOR_AMD:
2855 edx = &cpi->cpi_support[AMD_EDX_FEATURES];
2856 ecx = &cpi->cpi_support[AMD_ECX_FEATURES];
2857
4599 if (cpu->cpu_m.mcpu_cpi == NULL) {
4600 return;
4601 }
4602
4603 if (cpu->cpu_m.mcpu_cpi->cpi_mwait.buf_actual != NULL &&
4604 cpu->cpu_m.mcpu_cpi->cpi_mwait.size_actual > 0) {
4605 kmem_free(cpu->cpu_m.mcpu_cpi->cpi_mwait.buf_actual,
4606 cpu->cpu_m.mcpu_cpi->cpi_mwait.size_actual);
4607 }
4608
4609 cpu->cpu_m.mcpu_cpi->cpi_mwait.buf_actual = NULL;
4610 cpu->cpu_m.mcpu_cpi->cpi_mwait.size_actual = 0;
4611 }
4612
4613 void
4614 patch_tsc_read(int flag)
4615 {
4616 size_t cnt;
4617
4618 switch (flag) {
4619 case TSC_NONE:
4620 cnt = &_no_rdtsc_end - &_no_rdtsc_start;
4621 (void) memcpy((void *)tsc_read, (void *)&_no_rdtsc_start, cnt);
4622 break;
4623 case TSC_RDTSC_MFENCE:
4624 cnt = &_tsc_mfence_end - &_tsc_mfence_start;
4625 (void) memcpy((void *)tsc_read,
4626 (void *)&_tsc_mfence_start, cnt);
4627 break;
4628 case TSC_RDTSC_LFENCE:
4629 cnt = &_tsc_lfence_end - &_tsc_lfence_start;
4630 (void) memcpy((void *)tsc_read,
4631 (void *)&_tsc_lfence_start, cnt);
4632 break;
4633 case TSC_TSCP:
4634 cnt = &_tscp_end - &_tscp_start;
4635 (void) memcpy((void *)tsc_read, (void *)&_tscp_start, cnt);
4636 break;
4637 default:
4638 /* Bail for unexpected TSC types. (TSC_NONE covers 0) */
4639 cmn_err(CE_PANIC, "Unrecogized TSC type: %d", flag);
4640 break;
4641 }
4642 tsc_type = flag;
4643 }
4644
4645 int
4646 cpuid_deep_cstates_supported(void)
4647 {
4648 struct cpuid_info *cpi;
4649 struct cpuid_regs regs;
4650
4651 ASSERT(cpuid_checkpass(CPU, 1));
4652
4653 cpi = CPU->cpu_m.mcpu_cpi;
4654
4655 if (!is_x86_feature(x86_featureset, X86FSET_CPUID))
4656 return (0);
4657
4658 switch (cpi->cpi_vendor) {
4659 case X86_VENDOR_Intel:
4660 if (cpi->cpi_xmaxeax < 0x80000007)
4661 return (0);
4662
|