From a2a636ccad0c058fa1ac3c4620a7e808361d3b1d Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 11 Aug 2009 21:43:23 -0700 Subject: [PATCH] AMD64 - Sync machine-dependent bits from smtms. Submitted-by: Jordan Gordeev --- sys/cpu/amd64/include/cputypes.h | 35 ++-- .../amd64/include/floatingpoint.h} | 24 +-- sys/cpu/amd64/include/ieeefp.h | 195 +++++++++--------- sys/cpu/amd64/include/specialreg.h | 67 +++++- sys/cpu/amd64/include/types.h | 5 +- sys/platform/pc64/amd64/identcpu.c | 177 ++++++++++------ sys/platform/pc64/amd64/initcpu.c | 1 + sys/platform/pc64/amd64/ipl.s | 6 +- sys/platform/pc64/apic/apic_vector.s | 4 +- sys/platform/pc64/icu/icu_vector.s | 4 +- sys/platform/pc64/include/md_var.h | 1 + sys/platform/pc64/include/types.h | 3 + sys/platform/pc64/include/vmparam.h | 4 +- 13 files changed, 321 insertions(+), 205 deletions(-) copy sys/{platform/pc64/include/types.h => cpu/amd64/include/floatingpoint.h} (78%) diff --git a/sys/cpu/amd64/include/cputypes.h b/sys/cpu/amd64/include/cputypes.h index 14153a1c77..b4c034475b 100644 --- a/sys/cpu/amd64/include/cputypes.h +++ b/sys/cpu/amd64/include/cputypes.h @@ -34,32 +34,23 @@ /* * Classes of processor. */ -#define CPUCLASS_286 0 -#define CPUCLASS_386 1 -#define CPUCLASS_486 2 -#define CPUCLASS_586 3 -#define CPUCLASS_686 4 +#define CPUCLASS_X86 0 /* X86 */ +#define CPUCLASS_K8 1 /* K8 AMD64 class */ /* * Kinds of processor. */ -#define CPU_286 0 /* Intel 80286 */ -#define CPU_386SX 1 /* Intel 80386SX */ -#define CPU_386 2 /* Intel 80386DX */ -#define CPU_486SX 3 /* Intel 80486SX */ -#define CPU_486 4 /* Intel 80486DX */ -#define CPU_586 5 /* Intel P.....m (I hate lawyers; it's TM) */ -#define CPU_486DLC 6 /* Cyrix 486DLC */ -#define CPU_686 7 /* Pentium Pro */ -#define CPU_M1SC 8 /* Cyrix M1sc (aka 5x86) */ -#define CPU_M1 9 /* Cyrix M1 (aka 6x86) */ -#define CPU_BLUE 10 /* IBM BlueLighting CPU */ -#define CPU_M2 11 /* Cyrix M2 (aka enhanced 6x86 with MMX */ -#define CPU_NX586 12 /* NexGen (now AMD) 586 */ -#define CPU_CY486DX 13 /* Cyrix 486S/DX/DX2/DX4 */ -#define CPU_PII 14 /* Intel Pentium II */ -#define CPU_PIII 15 /* Intel Pentium III */ -#define CPU_P4 16 /* Intel Pentium 4 */ +#define CPU_X86 0 /* Intel */ +#define CPU_CLAWHAMMER 1 /* AMD Clawhammer */ +#define CPU_SLEDGEHAMMER 2 /* AMD Sledgehammer */ + +/* + * Vendors of processor. + */ +#define CPU_VENDOR_AMD 0x1022 /* AMD */ +#define CPU_VENDOR_IDT 0x111d /* Centaur/IDT/VIA */ +#define CPU_VENDOR_INTEL 0x8086 /* Intel */ +#define CPU_VENDOR_CENTAUR CPU_VENDOR_IDT #ifndef LOCORE extern int cpu; diff --git a/sys/platform/pc64/include/types.h b/sys/cpu/amd64/include/floatingpoint.h similarity index 78% copy from sys/platform/pc64/include/types.h copy to sys/cpu/amd64/include/floatingpoint.h index 1661e53eb5..0d68923c8c 100644 --- a/sys/platform/pc64/include/types.h +++ b/sys/cpu/amd64/include/floatingpoint.h @@ -1,6 +1,6 @@ /*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 1993 Andrew Moore, Talke Studio + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,19 +30,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)types.h 8.3 (Berkeley) 1/5/94 - * $FreeBSD: src/sys/i386/include/types.h,v 1.19.2.1 2001/03/21 10:50:58 peter Exp $ - * $DragonFly: src/sys/platform/pc64/include/types.h,v 1.2 2007/09/23 04:29:31 yanyh Exp $ + * from: @(#) floatingpoint.h 1.0 (Berkeley) 9/23/93 + * $FreeBSD: src/sys/i386/include/floatingpoint.h,v 1.10.2.1 2002/06/30 00:55:09 bde Exp $ + * $DragonFly: src/sys/cpu/i386/include/floatingpoint.h,v 1.5 2006/11/07 17:51:21 dillon Exp $ */ -#ifndef _MACHINE_TYPES_H_ -#define _MACHINE_TYPES_H_ +#ifndef _CPU_FLOATINGPOINT_H_ +#define _CPU_FLOATINGPOINT_H_ -#ifndef _MACHINE_STDINT_H_ -#include -#endif - -#include - -#endif /* !_MACHINE_TYPES_H_ */ +#include +#include +#endif /* !_CPU_FLOATINGPOINT_H_ */ diff --git a/sys/cpu/amd64/include/ieeefp.h b/sys/cpu/amd64/include/ieeefp.h index 21e16cca96..4e15f111f6 100644 --- a/sys/cpu/amd64/include/ieeefp.h +++ b/sys/cpu/amd64/include/ieeefp.h @@ -36,25 +36,26 @@ * $DragonFly: src/sys/cpu/amd64/include/ieeefp.h,v 1.1 2007/08/21 19:40:24 corecode Exp $ */ -/* - * IEEE floating point type and constant definitions. - */ - #ifndef _CPU_IEEEFP_H_ #define _CPU_IEEEFP_H_ /* - * FP rounding modes + * IEEE floating point type, constant and function definitions. + * XXX: {FP,SSE}*FLD and {FP,SSE}*OFF are undocumented pollution. + */ + +/* + * Rounding modes. */ typedef enum { FP_RN=0, /* round to nearest */ - FP_RM, /* round down to minus infinity */ - FP_RP, /* round up to plus infinity */ + FP_RM, /* round down towards minus infinity */ + FP_RP, /* round up towards plus infinity */ FP_RZ /* truncate */ } fp_rnd_t; /* - * FP precision modes + * Precision (i.e., rounding precision) modes. */ typedef enum { FP_PS=0, /* 24 bit (single-precision) */ @@ -66,7 +67,7 @@ typedef enum { #define fp_except_t int /* - * FP exception masks + * Exception bit masks. */ #define FP_X_INV 0x01 /* invalid operation */ #define FP_X_DNML 0x02 /* denormal */ @@ -77,23 +78,19 @@ typedef enum { #define FP_X_STK 0x40 /* stack fault */ /* - * FP registers + * FPU control word bit-field masks. */ -#define FP_MSKS_REG 0 /* exception masks */ -#define FP_PRC_REG 0 /* precision */ -#define FP_RND_REG 0 /* direction */ -#define FP_STKY_REG 1 /* sticky flags */ +#define FP_MSKS_FLD 0x3f /* exception masks field */ +#define FP_PRC_FLD 0x300 /* precision control field */ +#define FP_RND_FLD 0xc00 /* rounding control field */ /* - * FP register bit field masks + * FPU status word bit-field masks. */ -#define FP_MSKS_FLD 0x3f /* exception masks field */ -#define FP_PRC_FLD 0x300 /* precision control field */ -#define FP_RND_FLD 0xc00 /* round control field */ #define FP_STKY_FLD 0x3f /* sticky flags field */ /* - * SSE mxcsr register bit field masks + * SSE mxcsr register bit-field masks. */ #define SSE_STKY_FLD 0x3f /* exception flags */ #define SSE_DAZ_FLD 0x40 /* Denormals are zero */ @@ -102,15 +99,19 @@ typedef enum { #define SSE_FZ_FLD 0x8000 /* flush to zero on underflow */ /* - * FP register bit field offsets + * FPU control word bit-field offsets (shift counts). */ #define FP_MSKS_OFF 0 /* exception masks offset */ #define FP_PRC_OFF 8 /* precision control offset */ -#define FP_RND_OFF 10 /* round control offset */ +#define FP_RND_OFF 10 /* rounding control offset */ + +/* + * FPU status word bit-field offsets (shift counts). + */ #define FP_STKY_OFF 0 /* sticky flags offset */ /* - * SSE mxcsr register bit field offsets + * SSE mxcsr register bit-field offsets (shift counts). */ #define SSE_STKY_OFF 0 /* exception flags offset */ #define SSE_DAZ_OFF 6 /* DAZ exception mask offset */ @@ -120,14 +121,42 @@ typedef enum { #if defined(__GNUC__) && !defined(__cplusplus) +#define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) #define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) -#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) -#define __fldcw(addr) __asm __volatile("fldcw %0" : "=m" (*(addr))) #define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) +#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) #define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) -#define __ldmxcsr(addr) __asm __volatile("ldmxcsr %0" : "=m" (*(addr))) +#define __ldmxcsr(addr) __asm __volatile("ldmxcsr %0" : : "m" (*(addr))) #define __stmxcsr(addr) __asm __volatile("stmxcsr %0" : "=m" (*(addr))) +/* + * Load the control word. Be careful not to trap if there is a currently + * unmasked exception (ones that will become freshly unmasked are not a + * problem). This case must be handled by a save/restore of the + * environment or even of the full x87 state. Accessing the environment + * is very inefficient, so only do it when necessary. + */ +static __inline void +__fnldcw(unsigned short _cw, unsigned short _newcw) +{ + struct { + unsigned _cw; + unsigned _other[6]; + } _env; + unsigned short _sw; + + if ((_cw & FP_MSKS_FLD) != FP_MSKS_FLD) { + __fnstsw(&_sw); + if (((_sw & ~_cw) & FP_STKY_FLD) != 0) { + __fnstenv(&_env); + _env._cw = _newcw; + __fldenv(&_env); + return; + } + } + __fldcw(&_newcw); +} + /* * General notes about conflicting SSE vs FP status bits. * This code assumes that software will not fiddle with the control @@ -139,28 +168,27 @@ typedef enum { * merge the two together. I think. */ -/* Set rounding control */ -static __inline__ fp_rnd_t +static __inline fp_rnd_t __fpgetround(void) { unsigned short _cw; __fnstcw(&_cw); - return ((_cw & FP_RND_FLD) >> FP_RND_OFF); + return ((fp_rnd_t)((_cw & FP_RND_FLD) >> FP_RND_OFF)); } -static __inline__ fp_rnd_t +static __inline fp_rnd_t __fpsetround(fp_rnd_t _m) { - unsigned short _cw; - unsigned int _mxcsr; fp_rnd_t _p; + unsigned _mxcsr; + unsigned short _cw, _newcw; __fnstcw(&_cw); - _p = (_cw & FP_RND_FLD) >> FP_RND_OFF; - _cw &= ~FP_RND_FLD; - _cw |= (_m << FP_RND_OFF) & FP_RND_FLD; - __fldcw(&_cw); + _p = (fp_rnd_t)((_cw & FP_RND_FLD) >> FP_RND_OFF); + _newcw = _cw & ~FP_RND_FLD; + _newcw |= (_m << FP_RND_OFF) & FP_RND_FLD; + __fnldcw(_cw, _newcw); __stmxcsr(&_mxcsr); _mxcsr &= ~SSE_RND_FLD; _mxcsr |= (_m << SSE_RND_OFF) & SSE_RND_FLD; @@ -169,123 +197,102 @@ __fpsetround(fp_rnd_t _m) } /* - * Set precision for fadd/fsub/fsqrt etc x87 instructions + * Get or set the rounding precision for x87 arithmetic operations. * There is no equivalent SSE mode or control. */ -static __inline__ fp_prec_t + +static __inline fp_prec_t __fpgetprec(void) { unsigned short _cw; __fnstcw(&_cw); - return ((_cw & FP_PRC_FLD) >> FP_PRC_OFF); + return ((fp_prec_t)((_cw & FP_PRC_FLD) >> FP_PRC_OFF)); } -static __inline__ fp_prec_t -__fpsetprec(fp_rnd_t _m) +static __inline fp_prec_t +__fpsetprec(fp_prec_t _m) { - unsigned short _cw; fp_prec_t _p; + unsigned short _cw, _newcw; __fnstcw(&_cw); - _p = (_cw & FP_PRC_FLD) >> FP_PRC_OFF; - _cw &= ~FP_PRC_FLD; - _cw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; - __fldcw(&_cw); + _p = (fp_prec_t)((_cw & FP_PRC_FLD) >> FP_PRC_OFF); + _newcw = _cw & ~FP_PRC_FLD; + _newcw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; + __fnldcw(_cw, _newcw); return (_p); } /* - * Look at the exception masks - * Note that x87 masks are inverse of the fp*() functions - * API. ie: mask = 1 means disable for x87 and SSE, but - * for the fp*() api, mask = 1 means enabled. + * Get or set the exception mask. + * Note that the x87 mask bits are inverted by the API -- a mask bit of 1 + * means disable for x87 and SSE, but for fp*mask() it means enable. */ -static __inline__ fp_except_t + +static __inline fp_except_t __fpgetmask(void) { unsigned short _cw; __fnstcw(&_cw); - return ((~_cw) & FP_MSKS_FLD); + return ((~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF); } -static __inline__ fp_except_t +static __inline fp_except_t __fpsetmask(fp_except_t _m) { - unsigned short _cw; - unsigned int _mxcsr; fp_except_t _p; + unsigned _mxcsr; + unsigned short _cw, _newcw; __fnstcw(&_cw); - _p = (~_cw) & FP_MSKS_FLD; - _cw &= ~FP_MSKS_FLD; - _cw |= (~_m) & FP_MSKS_FLD; - __fldcw(&_cw); + _p = (~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF; + _newcw = _cw & ~FP_MSKS_FLD; + _newcw |= (~_m << FP_MSKS_OFF) & FP_MSKS_FLD; + __fnldcw(_cw, _newcw); __stmxcsr(&_mxcsr); /* XXX should we clear non-ieee SSE_DAZ_FLD and SSE_FZ_FLD ? */ _mxcsr &= ~SSE_MSKS_FLD; - _mxcsr |= ((~_m) << SSE_MSKS_OFF) & SSE_MSKS_FLD; + _mxcsr |= (~_m << SSE_MSKS_OFF) & SSE_MSKS_FLD; __ldmxcsr(&_mxcsr); return (_p); } -/* See which sticky exceptions are pending, and reset them */ -static __inline__ fp_except_t +static __inline fp_except_t __fpgetsticky(void) { + unsigned _ex, _mxcsr; unsigned short _sw; - unsigned int _mxcsr; - fp_except_t _ex; __fnstsw(&_sw); - _ex = _sw & FP_STKY_FLD; + _ex = (_sw & FP_STKY_FLD) >> FP_STKY_OFF; __stmxcsr(&_mxcsr); - _ex |= _mxcsr & SSE_STKY_FLD; - return (_ex); -} - -/* Note that this should really be called fpresetsticky() */ -static __inline__ fp_except_t -__fpsetsticky(fp_except_t _m) -{ - unsigned _env[7]; - unsigned int _mxcsr; - fp_except_t _p; - - __fnstenv(_env); - _p = _env[FP_STKY_REG] & _m; - __stmxcsr(&_mxcsr); - _p |= _mxcsr & SSE_STKY_FLD; - _env[FP_STKY_REG] &= ~_m; - __fldenv(_env); - _mxcsr &= ~_m; - __ldmxcsr(&_mxcsr); - return (_p); + _ex |= (_mxcsr & SSE_STKY_FLD) >> SSE_STKY_OFF; + return ((fp_except_t)_ex); } #endif /* __GNUC__ && !__cplusplus */ #if !defined(__IEEEFP_NOINLINES__) && !defined(__cplusplus) && defined(__GNUC__) -#define fpgetround() __fpgetround() -#define fpsetround(_m) __fpsetround(_m) -#define fpgetprec() __fpgetprec() -#define fpsetprec(_m) __fpsetprec(_m) #define fpgetmask() __fpgetmask() -#define fpsetmask(_m) __fpsetmask(_m) +#define fpgetprec() __fpgetprec() +#define fpgetround() __fpgetround() #define fpgetsticky() __fpgetsticky() -#define fpsetsticky(_m) __fpsetsticky(_m) +#define fpsetmask(m) __fpsetmask(m) +#define fpsetprec(m) __fpsetprec(m) +#define fpsetround(m) __fpsetround(m) /* Suppress prototypes in the MI header. */ #define _IEEEFP_INLINED_ 1 #else /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUC__ */ -/* Augment the userland declarations */ +/* Augment the userland declarations. */ __BEGIN_DECLS -extern fp_prec_t fpgetprec(void); -extern fp_prec_t fpsetprec(fp_prec_t); +fp_prec_t fpgetprec(void); +fp_prec_t fpsetprec(fp_prec_t); __END_DECLS #endif /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUC__ */ diff --git a/sys/cpu/amd64/include/specialreg.h b/sys/cpu/amd64/include/specialreg.h index 3f46a08de1..757c5bb31a 100644 --- a/sys/cpu/amd64/include/specialreg.h +++ b/sys/cpu/amd64/include/specialreg.h @@ -115,6 +115,7 @@ #define CPUID_PBE 0x80000000 #define CPUID2_SSE3 0x00000001 +#define CPUID2_DTES64 0x00000004 #define CPUID2_MON 0x00000008 #define CPUID2_DS_CPL 0x00000010 #define CPUID2_VMX 0x00000020 @@ -127,6 +128,10 @@ #define CPUID2_XTPR 0x00004000 #define CPUID2_PDCM 0x00008000 #define CPUID2_DCA 0x00040000 +#define CPUID2_SSE41 0x00080000 +#define CPUID2_SSE42 0x00100000 +#define CPUID2_X2APIC 0x00200000 +#define CPUID2_POPCNT 0x00800000 /* * Important bits in the AMD extended cpuid flags @@ -147,7 +152,16 @@ #define AMDID2_SVM 0x00000004 #define AMDID2_EXT_APIC 0x00000008 #define AMDID2_CR8 0x00000010 +#define AMDID2_ABM 0x00000020 +#define AMDID2_SSE4A 0x00000040 +#define AMDID2_MAS 0x00000080 #define AMDID2_PREFETCH 0x00000100 +#define AMDID2_OSVW 0x00000200 +#define AMDID2_IBS 0x00000400 +#define AMDID2_SSE5 0x00000800 +#define AMDID2_SKINIT 0x00001000 +#define AMDID2_WDT 0x00002000 + /* * CPUID instruction 1 ebx info @@ -162,6 +176,13 @@ */ #define AMDID_CMP_CORES 0x000000ff +/* + * CPUID manufacturers identifiers + */ +#define AMD_VENDOR_ID "AuthenticAMD" +#define CENTAUR_VENDOR_ID "CentaurHauls" +#define INTEL_VENDOR_ID "GenuineIntel" + /* * Model-specific registers for the i386 family */ @@ -182,7 +203,7 @@ #define MSR_BIOS_SIGN 0x08b #define MSR_PERFCTR0 0x0c1 #define MSR_PERFCTR1 0x0c2 -#define MSR_IA32_EXT_CONFIG 0x0ee /* Undocumented. Core Solo/Duo only */ +#define MSR_IA32_EXT_CONFIG 0x0ee /* Undocumented. Core Solo/Duo only */ #define MSR_MTRRcap 0x0fe #define MSR_BBL_CR_ADDR 0x116 #define MSR_BBL_CR_DECC 0x118 @@ -258,9 +279,24 @@ /* * Constants related to MTRRs */ +#define MTRR_UNCACHEABLE 0x00 +#define MTRR_WRITE_COMBINING 0x01 +#define MTRR_WRITE_THROUGH 0x04 +#define MTRR_WRITE_PROTECTED 0x05 +#define MTRR_WRITE_BACK 0x06 #define MTRR_N64K 8 /* numbers of fixed-size entries */ #define MTRR_N16K 16 #define MTRR_N4K 64 +#define MTRR_CAP_WC 0x0000000000000400UL +#define MTRR_CAP_FIXED 0x0000000000000100UL +#define MTRR_CAP_VCNT 0x00000000000000ffUL +#define MTRR_DEF_ENABLE 0x0000000000000800UL +#define MTRR_DEF_FIXED_ENABLE 0x0000000000000400UL +#define MTRR_DEF_TYPE 0x00000000000000ffUL +#define MTRR_PHYSBASE_PHYSBASE 0x000ffffffffff000UL +#define MTRR_PHYSBASE_TYPE 0x00000000000000ffUL +#define MTRR_PHYSMASK_PHYSMASK 0x000ffffffffff000UL +#define MTRR_PHYSMASK_VALID 0x0000000000000800UL /* Performance Control Register (5x86 only). */ #define PCR0 0x20 @@ -277,6 +313,34 @@ #define DIR0 0xfe #define DIR1 0xff +/* + * Machine Check register constants. + */ +#define MCG_CAP_COUNT 0x000000ff +#define MCG_CAP_CTL_P 0x00000100 +#define MCG_CAP_EXT_P 0x00000200 +#define MCG_CAP_TES_P 0x00000800 +#define MCG_CAP_EXT_CNT 0x00ff0000 +#define MCG_STATUS_RIPV 0x00000001 +#define MCG_STATUS_EIPV 0x00000002 +#define MCG_STATUS_MCIP 0x00000004 +#define MCG_CTL_ENABLE 0xffffffffffffffffUL +#define MCG_CTL_DISABLE 0x0000000000000000UL +#define MSR_MC_CTL(x) (MSR_MC0_CTL + (x) * 4) +#define MSR_MC_STATUS(x) (MSR_MC0_STATUS + (x) * 4) +#define MSR_MC_ADDR(x) (MSR_MC0_ADDR + (x) * 4) +#define MSR_MC_MISC(x) (MSR_MC0_MISC + (x) * 4) +#define MC_STATUS_MCA_ERROR 0x000000000000ffffUL +#define MC_STATUS_MODEL_ERROR 0x00000000ffff0000UL +#define MC_STATUS_OTHER_INFO 0x01ffffff00000000UL +#define MC_STATUS_PCC 0x0200000000000000UL +#define MC_STATUS_ADDRV 0x0400000000000000UL +#define MC_STATUS_MISCV 0x0800000000000000UL +#define MC_STATUS_EN 0x1000000000000000UL +#define MC_STATUS_UC 0x2000000000000000UL +#define MC_STATUS_OVER 0x4000000000000000UL +#define MC_STATUS_VAL 0x8000000000000000UL + /* * The following four 3-byte registers control the non-cacheable regions. * These registers must be written as three separate bytes. @@ -396,5 +460,6 @@ #define MSR_IORRMASK1 0xc0010019 #define MSR_TOP_MEM 0xc001001a /* boundary for ram below 4G */ #define MSR_TOP_MEM2 0xc001001d /* boundary for ram above 4G */ +#define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */ #endif /* !_CPU_SPECIALREG_H_ */ diff --git a/sys/cpu/amd64/include/types.h b/sys/cpu/amd64/include/types.h index 8daa233ccf..2defbb10b7 100644 --- a/sys/cpu/amd64/include/types.h +++ b/sys/cpu/amd64/include/types.h @@ -53,12 +53,14 @@ typedef struct label_t { typedef __uint64_t vm_offset_t; /* address space bounded offset */ typedef __uint64_t vm_size_t; /* address space bounded size */ typedef __uint64_t vm_pindex_t; /* physical page index */ +typedef __int64_t __segsz_t; /* segment size */ typedef __int64_t register_t; typedef __uint64_t u_register_t; #elif defined(__i386__) typedef unsigned int vm_offset_t; /* address space bounded offset */ typedef unsigned int vm_size_t; /* address space bounded size */ typedef unsigned int vm_pindex_t; /* physical page index */ +typedef __int32_t __segsz_t; /* segment size */ typedef __int32_t register_t; typedef __uint32_t u_register_t; #endif @@ -89,8 +91,5 @@ typedef __uint32_t cpumask_t; /* mask representing a set of cpus */ #define PDESIZE sizeof(pd_entry_t) /* for assembly files */ #define PTESIZE sizeof(pt_entry_t) /* for assembly files */ -/* Interrupt mask (spl, xxx_imask, etc) */ -typedef __uint32_t intrmask_t; - #endif /* !_CPU_TYPES_H_ */ diff --git a/sys/platform/pc64/amd64/identcpu.c b/sys/platform/pc64/amd64/identcpu.c index 3d71a94c47..0fdcacb67e 100644 --- a/sys/platform/pc64/amd64/identcpu.c +++ b/sys/platform/pc64/amd64/identcpu.c @@ -44,9 +44,6 @@ #include #include -#if JG -#include -#endif #include #include #include @@ -62,18 +59,16 @@ #include #include -#if JG -#include -#endif - /* XXX - should be in header file: */ void printcpuinfo(void); void identify_cpu(void); void earlysetcpuclass(void); void panicifcpuunsupported(void); +static u_int find_cpu_vendor_id(void); static void print_AMD_info(void); static void print_AMD_assoc(int i); +static void print_via_padlock_info(void); int cpu_class; char machine[] = "amd64"; @@ -94,7 +89,17 @@ static struct { char *cpu_name; int cpu_class; } amd64_cpus[] = { - { "64-bit-cpu", CPUCLASS_686 } + { "Clawhammer", CPUCLASS_K8 }, /* CPU_CLAWHAMMER */ + { "Sledgehammer", CPUCLASS_K8 }, /* CPU_SLEDGEHAMMER */ +}; + +static struct { + char *vendor; + u_int vendor_id; +} cpu_vendors[] = { + { INTEL_VENDOR_ID, CPU_VENDOR_INTEL }, /* GenuineIntel */ + { AMD_VENDOR_ID, CPU_VENDOR_AMD }, /* AuthenticAMD */ + { CENTAUR_VENDOR_ID, CPU_VENDOR_CENTAUR }, /* CentaurHauls */ }; int cpu_cores; @@ -124,24 +129,33 @@ printcpuinfo(void) } } - if (strcmp(cpu_vendor, "GenuineIntel") == 0) { + switch (cpu_vendor_id) { + case CPU_VENDOR_INTEL: /* Please make up your mind folks! */ strcat(cpu_model, "EM64T"); - } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { + break; + case CPU_VENDOR_AMD: /* * Values taken from AMD Processor Recognition * http://www.amd.com/K6/k6docs/pdf/20734g.pdf * (also describes ``Features'' encodings. */ strcpy(cpu_model, "AMD "); - switch (cpu_id & 0xF00) { - case 0xf00: + if ((cpu_id & 0xf00) == 0xf00) strcat(cpu_model, "AMD64 Processor"); - break; - default: + else strcat(cpu_model, "Unknown"); - break; - } + break; + case CPU_VENDOR_CENTAUR: + strcpy(cpu_model, "VIA "); + if ((cpu_id & 0xff0) == 0x6f0) + strcat(cpu_model, "Nano Processor"); + else + strcat(cpu_model, "Unknown"); + break; + default: + strcat(cpu_model, "Unknown"); + break; } /* @@ -155,26 +169,26 @@ printcpuinfo(void) strcpy(cpu_model, brand); kprintf("%s (", cpu_model); - -#if JG - hw_clockrate = (tsc_freq + 5000) / 1000000; - kprintf("%jd.%02d-MHz ", - (intmax_t)(tsc_freq + 4999) / 1000000, - (u_int)((tsc_freq + 4999) / 10000) % 100); -#endif - switch(cpu_class) { + case CPUCLASS_K8: + hw_clockrate = (tsc_frequency + 5000) / 1000000; + kprintf("%jd.%02d-MHz ", + (intmax_t)(tsc_frequency + 4999) / 1000000, + (u_int)((tsc_frequency + 4999) / 10000) % 100); + kprintf("K8"); + break; default: - kprintf("64-bit-class"); + kprintf("Unknown"); /* will panic below... */ } kprintf("-class CPU)\n"); - if(*cpu_vendor) - kprintf(" Origin = \"%s\"",cpu_vendor); - if(cpu_id) + if (*cpu_vendor) + kprintf(" Origin = \"%s\"", cpu_vendor); + if (cpu_id) kprintf(" Id = 0x%x", cpu_id); - if (strcmp(cpu_vendor, "GenuineIntel") == 0 || - strcmp(cpu_vendor, "AuthenticAMD") == 0) { + if (cpu_vendor_id == CPU_VENDOR_INTEL || + cpu_vendor_id == CPU_VENDOR_AMD || + cpu_vendor_id == CPU_VENDOR_CENTAUR) { kprintf(" Stepping = %u", cpu_id & 0xf); if (cpu_high > 0) { u_int cmp = 1, htt = 1; @@ -316,15 +330,15 @@ printcpuinfo(void) "\003SVM" /* Secure Virtual Mode */ "\004ExtAPIC" /* Extended APIC register */ "\005CR8" /* CR8 in legacy mode */ - "\006" - "\007" - "\010" + "\006ABM" /* LZCNT instruction */ + "\007SSE4A" /* SSE4A */ + "\010MAS" /* Misaligned SSE mode */ "\011Prefetch" /* 3DNow! Prefetch/PrefetchW */ - "\012" - "\013" - "\014" - "\015" - "\016" + "\012OSVW" /* OS visible workaround */ + "\013IBS" /* Instruction based sampling */ + "\014SSE5" /* SSE5 */ + "\015SKINIT" /* SKINIT/STGI */ + "\016WDT" /* Watchdog timer */ "\017" "\020" "\021" @@ -346,8 +360,11 @@ printcpuinfo(void) ); } - if (cpu_feature & CPUID_HTT && strcmp(cpu_vendor, - "AuthenticAMD") == 0) + if (cpu_vendor_id == CPU_VENDOR_CENTAUR) + print_via_padlock_info(); + + if ((cpu_feature & CPUID_HTT) && + cpu_vendor_id == CPU_VENDOR_AMD) cpu_feature &= ~CPUID_HTT; /* @@ -356,10 +373,10 @@ printcpuinfo(void) */ if (cpu_feature & CPUID_HTT) htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16; - if (strcmp(cpu_vendor, "AuthenticAMD") == 0 && + if (cpu_vendor_id == CPU_VENDOR_AMD && (amd_feature2 & AMDID2_CMP)) cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1; - else if (strcmp(cpu_vendor, "GenuineIntel") == 0 && + else if (cpu_vendor_id == CPU_VENDOR_INTEL && (cpu_high >= 4)) { cpuid_count(4, 0, regs); if ((regs[0] & 0x1f) != 0) @@ -381,41 +398,30 @@ printcpuinfo(void) if (!bootverbose) return; - if (strcmp(cpu_vendor, "AuthenticAMD") == 0) + if (cpu_vendor_id == CPU_VENDOR_AMD) print_AMD_info(); } void panicifcpuunsupported(void) { + #ifndef HAMMER_CPU #error "You need to specify a cpu type" #endif -#if 0 /* * Now that we have told the user what they have, * let them know if that machine type isn't configured. */ switch (cpu_class) { - /* - * A 286 and 386 should not make it this far, anyway. - */ - case CPUCLASS_286: - case CPUCLASS_386: -#if !defined(I486_CPU) - case CPUCLASS_486: -#endif -#if !defined(I586_CPU) - case CPUCLASS_586: -#endif -#if !defined(I686_CPU) - case CPUCLASS_686: + case CPUCLASS_X86: +#ifndef HAMMER_CPU + case CPUCLASS_K8: #endif panic("CPU class not configured"); default: break; } -#endif } @@ -437,7 +443,7 @@ EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL, #endif /* - * Final stage of CPU identification. -- Should I check TI? + * Final stage of CPU identification. */ void identify_cpu(void) @@ -450,6 +456,7 @@ identify_cpu(void) ((u_int *)&cpu_vendor)[1] = regs[3]; ((u_int *)&cpu_vendor)[2] = regs[2]; cpu_vendor[12] = '\0'; + cpu_vendor_id = find_cpu_vendor_id(); do_cpuid(1, regs); cpu_id = regs[0]; @@ -457,8 +464,9 @@ identify_cpu(void) cpu_feature = regs[3]; cpu_feature2 = regs[2]; - if (strcmp(cpu_vendor, "GenuineIntel") == 0 || - strcmp(cpu_vendor, "AuthenticAMD") == 0) { + if (cpu_vendor_id == CPU_VENDOR_INTEL || + cpu_vendor_id == CPU_VENDOR_AMD || + cpu_vendor_id == CPU_VENDOR_CENTAUR) { do_cpuid(0x80000000, regs); cpu_exthigh = regs[0]; } @@ -473,7 +481,18 @@ identify_cpu(void) } /* XXX */ - cpu = 0; + cpu = CPU_CLAWHAMMER; +} + +static u_int +find_cpu_vendor_id(void) +{ + int i; + + for (i = 0; i < sizeof(cpu_vendors) / sizeof(cpu_vendors[0]); i++) + if (strcmp(cpu_vendor, cpu_vendors[i].vendor) == 0) + return (cpu_vendors[i].vendor_id); + return (0); } static void @@ -564,3 +583,37 @@ print_AMD_info(void) print_AMD_l2_assoc((regs[2] >> 12) & 0x0f); } } + +static void +print_via_padlock_info(void) +{ + u_int regs[4]; + + /* Check for supported models. */ + switch (cpu_id & 0xff0) { + case 0x690: + if ((cpu_id & 0xf) < 3) + return; + case 0x6a0: + case 0x6d0: + case 0x6f0: + break; + default: + return; + } + + do_cpuid(0xc0000000, regs); + if (regs[0] >= 0xc0000001) + do_cpuid(0xc0000001, regs); + else + return; + + kprintf("\n VIA Padlock Features=0x%b", regs[3], + "\020" + "\003RNG" /* RNG */ + "\007AES" /* ACE */ + "\011AES-CTR" /* ACE2 */ + "\013SHA1,SHA256" /* PHE */ + "\015RSA" /* PMM */ + ); +} diff --git a/sys/platform/pc64/amd64/initcpu.c b/sys/platform/pc64/amd64/initcpu.c index 1c4ce0b778..77dadcf35d 100644 --- a/sys/platform/pc64/amd64/initcpu.c +++ b/sys/platform/pc64/amd64/initcpu.c @@ -59,6 +59,7 @@ u_int cpu_id; /* Stepping ID */ u_int cpu_procinfo; /* HyperThreading Info / Brand Index / CLFUSH */ u_int cpu_procinfo2; /* Multicore info */ char cpu_vendor[20]; /* CPU Origin code */ +u_int cpu_vendor_id; /* CPU vendor ID */ u_int cpu_fxsr; /* SSE enabled */ u_int cpu_mxcsr_mask; /* Valid bits in mxcsr */ diff --git a/sys/platform/pc64/amd64/ipl.s b/sys/platform/pc64/amd64/ipl.s index c830cce396..e81c10e25a 100644 --- a/sys/platform/pc64/amd64/ipl.s +++ b/sys/platform/pc64/amd64/ipl.s @@ -316,7 +316,7 @@ doreti_ipiq: subq $8,%rsp /* trapframe->intrframe */ movq %rsp,%rdi /* pass frame by ref (C arg) */ call lwkt_process_ipiq_frame - addq $8,%rsp + addq $8,%rsp /* intrframe->trapframe */ decl PCPU(intr_nesting_level) movl %r12d,%eax /* restore cpl for loop */ jmp doreti_next @@ -325,10 +325,10 @@ doreti_timer: movl %eax,%r12d /* save cpl (can't use stack) */ incl PCPU(intr_nesting_level) andl $~RQF_TIMER,PCPU(reqflags) - subq $16,%rsp /* add dummy vec and ppl */ + subq $8,%rsp /* trapframe->intrframe */ movq %rsp,%rdi /* pass frame by ref (C arg) */ call lapic_timer_process_frame - addq $16,%rsp + addq $8,%rsp /* intrframe->trapframe */ decl PCPU(intr_nesting_level) movl %r12d,%eax /* restore cpl for loop */ jmp doreti_next diff --git a/sys/platform/pc64/apic/apic_vector.s b/sys/platform/pc64/apic/apic_vector.s index 349dd617e7..7a3635420e 100644 --- a/sys/platform/pc64/apic/apic_vector.s +++ b/sys/platform/pc64/apic/apic_vector.s @@ -142,9 +142,9 @@ IDTVEC(vec_name) ; \ andl $~IRQ_LBIT(irq_num),PCPU(fpending) ; \ pushq $irq_num ; /* trapframe -> intrframe */ \ movq %rsp, %rdi ; /* pass frame by reference */ \ - addl $TDPRI_CRIT,TD_PRI(%ebx) ; \ + addl $TDPRI_CRIT,TD_PRI(%rbx) ; \ call ithread_fast_handler ; /* returns 0 to unmask */ \ - subl $TDPRI_CRIT,TD_PRI(%ebx) ; \ + subl $TDPRI_CRIT,TD_PRI(%rbx) ; \ addq $8, %rsp ; /* intrframe -> trapframe */ \ UNMASK_IRQ(irq_num) ; \ 5: ; \ diff --git a/sys/platform/pc64/icu/icu_vector.s b/sys/platform/pc64/icu/icu_vector.s index b6fd834f3a..d73b7256ec 100644 --- a/sys/platform/pc64/icu/icu_vector.s +++ b/sys/platform/pc64/icu/icu_vector.s @@ -153,9 +153,9 @@ IDTVEC(vec_name) ; \ andl $~IRQ_LBIT(irq_num),PCPU(fpending) ; \ pushq $irq_num ; \ movq %rsp,%rdi ; /* rdi = call argument */ \ - addl $TDPRI_CRIT,TD_PRI(%ebx) ; \ + addl $TDPRI_CRIT,TD_PRI(%rbx) ; \ call ithread_fast_handler ; /* returns 0 to unmask int */ \ - subl $TDPRI_CRIT,TD_PRI(%ebx) ; \ + subl $TDPRI_CRIT,TD_PRI(%rbx) ; \ addq $8,%rsp ; /* intr frame -> trap frame */ \ UNMASK_IRQ(icu, irq_num) ; \ 5: ; \ diff --git a/sys/platform/pc64/include/md_var.h b/sys/platform/pc64/include/md_var.h index fb208f3efa..067909fe8d 100644 --- a/sys/platform/pc64/include/md_var.h +++ b/sys/platform/pc64/include/md_var.h @@ -53,6 +53,7 @@ extern u_int cpu_id; extern u_int cpu_procinfo; extern u_int cpu_procinfo2; extern char cpu_vendor[]; +extern u_int cpu_vendor_id; extern char kstack[]; extern char sigcode[]; extern int szsigcode; diff --git a/sys/platform/pc64/include/types.h b/sys/platform/pc64/include/types.h index 1661e53eb5..20f5d3ea4d 100644 --- a/sys/platform/pc64/include/types.h +++ b/sys/platform/pc64/include/types.h @@ -44,5 +44,8 @@ #include +/* Interrupt mask (spl, xxx_imask, etc) */ +typedef __uint32_t intrmask_t; + #endif /* !_MACHINE_TYPES_H_ */ diff --git a/sys/platform/pc64/include/vmparam.h b/sys/platform/pc64/include/vmparam.h index b660e21d21..86c467e146 100644 --- a/sys/platform/pc64/include/vmparam.h +++ b/sys/platform/pc64/include/vmparam.h @@ -57,13 +57,13 @@ #define DFLDSIZ (128UL*1024*1024) /* initial data size limit */ #endif #ifndef MAXDSIZ -#define MAXDSIZ (256UL*1024*1024) /* max data size */ +#define MAXDSIZ (32768UL*1024*1024) /* max data size */ #endif #ifndef DFLSSIZ #define DFLSSIZ (8UL*1024*1024) /* initial stack size limit */ #endif #ifndef MAXSSIZ -#define MAXSSIZ (128UL*1024*1024) /* max stack size */ +#define MAXSSIZ (512UL*1024*1024) /* max stack size */ #endif #ifndef SGROWSIZ #define SGROWSIZ (128UL*1024) /* amount to grow stack */ -- 2.41.0