1122940Speter/*- 240003Skato * Copyright (c) KATO Takenori, 1997, 1998. 324113Skato * 424113Skato * All rights reserved. Unpublished rights reserved under the copyright 524113Skato * laws of Japan. 624113Skato * 724113Skato * Redistribution and use in source and binary forms, with or without 824113Skato * modification, are permitted provided that the following conditions 924113Skato * are met: 1024113Skato * 1124113Skato * 1. Redistributions of source code must retain the above copyright 1224113Skato * notice, this list of conditions and the following disclaimer as 1324113Skato * the first lines of this file unmodified. 1424113Skato * 2. Redistributions in binary form must reproduce the above copyright 1524113Skato * notice, this list of conditions and the following disclaimer in the 1624113Skato * documentation and/or other materials provided with the distribution. 1724113Skato * 1824113Skato * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1924113Skato * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2024113Skato * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2124113Skato * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2224113Skato * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2324113Skato * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2424113Skato * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2524113Skato * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2624113Skato * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2724113Skato * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2824113Skato */ 2924113Skato 30118031Sobrien#include <sys/cdefs.h> 31118031Sobrien__FBSDID("$FreeBSD$"); 32118031Sobrien 3324113Skato#include "opt_cpu.h" 3424113Skato 3524113Skato#include <sys/param.h> 3624113Skato#include <sys/kernel.h> 37242433Skib#include <sys/pcpu.h> 3824113Skato#include <sys/systm.h> 3979609Speter#include <sys/sysctl.h> 4024113Skato 4124113Skato#include <machine/cputypes.h> 4224113Skato#include <machine/md_var.h> 4324113Skato#include <machine/specialreg.h> 4424113Skato 45130224Speter#include <vm/vm.h> 46130224Speter#include <vm/pmap.h> 4740003Skato 48109700Sjhbstatic int hw_instruction_sse; 4979609SpeterSYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD, 50109700Sjhb &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU"); 51199067Skuriyama/* 52199067Skuriyama * -1: automatic (default) 53199067Skuriyama * 0: keep enable CLFLUSH 54199067Skuriyama * 1: force disable CLFLUSH 55199067Skuriyama */ 56199067Skuriyamastatic int hw_clflush_disable = -1; 5779609Speter 58114349Speterint cpu; /* Are we 386, 386sx, 486, etc? */ 59114349Speteru_int cpu_feature; /* Feature flags */ 60130224Speteru_int cpu_feature2; /* Feature flags */ 61151348Sjkimu_int amd_feature; /* AMD feature flags */ 62151348Sjkimu_int amd_feature2; /* AMD feature flags */ 63184101Sjkimu_int amd_pminfo; /* AMD advanced power management info */ 64187109Sjkimu_int via_feature_rng; /* VIA RNG features */ 65187109Sjkimu_int via_feature_xcrypt; /* VIA ACE features */ 66114349Speteru_int cpu_high; /* Highest arg to CPUID */ 67130224Speteru_int cpu_exthigh; /* Highest arg to extended CPUID */ 68114349Speteru_int cpu_id; /* Stepping ID */ 69114349Speteru_int cpu_procinfo; /* HyperThreading Info / Brand Index / CLFUSH */ 70151348Sjkimu_int cpu_procinfo2; /* Multicore info */ 71114349Speterchar cpu_vendor[20]; /* CPU Origin code */ 72185341Sjkimu_int cpu_vendor_id; /* CPU vendor ID */ 73109700Sjhbu_int cpu_fxsr; /* SSE enabled */ 74159783Sdavidxuu_int cpu_mxcsr_mask; /* Valid bits in mxcsr */ 75195820Skibu_int cpu_clflush_line_size = 32; 76242432Skibu_int cpu_stdext_feature; 77230426Skibu_int cpu_max_ext_state_size; 78253747Savgu_int cpu_mon_mwait_flags; /* MONITOR/MWAIT flags (CPUID.05H.ECX) */ 79253747Savgu_int cpu_mon_min_size; /* MONITOR minimum range size, bytes */ 80253747Savgu_int cpu_mon_max_size; /* MONITOR minimum range size, bytes */ 8182261Speter 82187109SjkimSYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD, 83220018Sjkim &via_feature_rng, 0, "VIA RNG feature available in CPU"); 84187109SjkimSYSCTL_UINT(_hw, OID_AUTO, via_feature_xcrypt, CTLFLAG_RD, 85220018Sjkim &via_feature_xcrypt, 0, "VIA xcrypt feature available in CPU"); 86187109Sjkim 87233702Sjkimstatic void 88233702Sjkiminit_amd(void) 89233702Sjkim{ 90233702Sjkim 91233702Sjkim /* 92233702Sjkim * Work around Erratum 721 for Family 10h and 12h processors. 93233702Sjkim * These processors may incorrectly update the stack pointer 94233702Sjkim * after a long series of push and/or near-call instructions, 95233702Sjkim * or a long series of pop and/or near-return instructions. 96233702Sjkim * 97233702Sjkim * http://support.amd.com/us/Processor_TechDocs/41322_10h_Rev_Gd.pdf 98233702Sjkim * http://support.amd.com/us/Processor_TechDocs/44739_12h_Rev_Gd.pdf 99239125Skib * 100239125Skib * Hypervisors do not provide access to the errata MSR, 101239125Skib * causing #GP exception on attempt to apply the errata. The 102239125Skib * MSR write shall be done on host and persist globally 103239125Skib * anyway, so do not try to do it when under virtualization. 104233702Sjkim */ 105233702Sjkim switch (CPUID_TO_FAMILY(cpu_id)) { 106233702Sjkim case 0x10: 107233702Sjkim case 0x12: 108239125Skib if ((cpu_feature2 & CPUID2_HV) == 0) 109239125Skib wrmsr(0xc0011029, rdmsr(0xc0011029) | 1); 110233702Sjkim break; 111233702Sjkim } 112233702Sjkim} 113233702Sjkim 11424113Skato/* 115220018Sjkim * Initialize special VIA features 116187109Sjkim */ 117187109Sjkimstatic void 118187109Sjkiminit_via(void) 119187109Sjkim{ 120187109Sjkim u_int regs[4], val; 121187109Sjkim 122220018Sjkim /* 123220018Sjkim * Check extended CPUID for PadLock features. 124220018Sjkim * 125220018Sjkim * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/programming_guide.pdf 126220018Sjkim */ 127187109Sjkim do_cpuid(0xc0000000, regs); 128220018Sjkim if (regs[0] >= 0xc0000001) { 129187109Sjkim do_cpuid(0xc0000001, regs); 130187109Sjkim val = regs[3]; 131187109Sjkim } else 132220018Sjkim return; 133187109Sjkim 134220018Sjkim /* Enable RNG if present. */ 135220018Sjkim if ((val & VIA_CPUID_HAS_RNG) != 0) { 136187109Sjkim via_feature_rng = VIA_HAS_RNG; 137220018Sjkim wrmsr(0x110B, rdmsr(0x110B) | VIA_CPUID_DO_RNG); 138187109Sjkim } 139220018Sjkim 140220018Sjkim /* Enable PadLock if present. */ 141220018Sjkim if ((val & VIA_CPUID_HAS_ACE) != 0) 142187109Sjkim via_feature_xcrypt |= VIA_HAS_AES; 143220018Sjkim if ((val & VIA_CPUID_HAS_ACE2) != 0) 144187109Sjkim via_feature_xcrypt |= VIA_HAS_AESCTR; 145220018Sjkim if ((val & VIA_CPUID_HAS_PHE) != 0) 146187109Sjkim via_feature_xcrypt |= VIA_HAS_SHA; 147220018Sjkim if ((val & VIA_CPUID_HAS_PMM) != 0) 148187109Sjkim via_feature_xcrypt |= VIA_HAS_MM; 149220018Sjkim if (via_feature_xcrypt != 0) 150220018Sjkim wrmsr(0x1107, rdmsr(0x1107) | (1 << 28)); 151187109Sjkim} 152187109Sjkim 153187109Sjkim/* 154130224Speter * Initialize CPU control registers 15579609Speter */ 15679609Spetervoid 157130224Speterinitializecpu(void) 15879609Speter{ 159130224Speter uint64_t msr; 160242433Skib uint32_t cr4; 161130224Speter 162242433Skib cr4 = rcr4(); 16379609Speter if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) { 164242433Skib cr4 |= CR4_FXSR | CR4_XMM; 16579609Speter cpu_fxsr = hw_instruction_sse = 1; 16679609Speter } 167242433Skib if (cpu_stdext_feature & CPUID_STDEXT_FSGSBASE) 168242433Skib cr4 |= CR4_FSGSBASE; 169242433Skib 170242433Skib /* 171242433Skib * Postpone enabling the SMEP on the boot CPU until the page 172242433Skib * tables are switched from the boot loader identity mapping 173242433Skib * to the kernel tables. The boot loader enables the U bit in 174242433Skib * its tables. 175242433Skib */ 176242433Skib if (!IS_BSP() && (cpu_stdext_feature & CPUID_STDEXT_SMEP)) 177242433Skib cr4 |= CR4_SMEP; 178242433Skib load_cr4(cr4); 179130224Speter if ((amd_feature & AMDID_NX) != 0) { 180130224Speter msr = rdmsr(MSR_EFER) | EFER_NXE; 181130224Speter wrmsr(MSR_EFER, msr); 182130224Speter pg_nx = PG_NX; 18324113Skato } 184233702Sjkim switch (cpu_vendor_id) { 185233702Sjkim case CPU_VENDOR_AMD: 186233702Sjkim init_amd(); 187233702Sjkim break; 188233702Sjkim case CPU_VENDOR_CENTAUR: 189187109Sjkim init_via(); 190233702Sjkim break; 191233702Sjkim } 192199253Skib} 193195820Skib 194199253Skibvoid 195254374Sbrooksinitializecpucache(void) 196199253Skib{ 197199253Skib 198195820Skib /* 199195820Skib * CPUID with %eax = 1, %ebx returns 200195820Skib * Bits 15-8: CLFLUSH line size 201195820Skib * (Value * 8 = cache line size in bytes) 202195820Skib */ 203195820Skib if ((cpu_feature & CPUID_CLFSH) != 0) 204195820Skib cpu_clflush_line_size = ((cpu_procinfo >> 8) & 0xff) * 8; 205197663Skib /* 206210774Sjhb * XXXKIB: (temporary) hack to work around traps generated 207210774Sjhb * when CLFLUSHing APIC register window under virtualization 208210774Sjhb * environments. These environments tend to disable the 209210774Sjhb * CPUID_SS feature even though the native CPU supports it. 210197663Skib */ 211199067Skuriyama TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable); 212210774Sjhb if (vm_guest != VM_GUEST_NO && hw_clflush_disable == -1) 213197663Skib cpu_feature &= ~CPUID_CLFSH; 214199067Skuriyama /* 215199067Skuriyama * Allow to disable CLFLUSH feature manually by 216210774Sjhb * hw.clflush_disable tunable. 217199067Skuriyama */ 218199215Skuriyama if (hw_clflush_disable == 1) 219199067Skuriyama cpu_feature &= ~CPUID_CLFSH; 22024113Skato} 221