diff options
author | stas <stas@FreeBSD.org> | 2008-08-08 16:26:53 +0000 |
---|---|---|
committer | stas <stas@FreeBSD.org> | 2008-08-08 16:26:53 +0000 |
commit | a782fc10febc1bf57b9653c29ee514c128c78b4b (patch) | |
tree | a44ebf1877459512b877e0d0b6c6c93744374604 /sys/amd64 | |
parent | 7d2bdda0cd5d8adc83d5ae3dd62dd4911be922c1 (diff) | |
download | FreeBSD-src-a782fc10febc1bf57b9653c29ee514c128c78b4b.zip FreeBSD-src-a782fc10febc1bf57b9653c29ee514c128c78b4b.tar.gz |
- Add cpuctl(4) pseudo-device driver to provide access to some low-level
features of CPUs like reading/writing machine-specific registers,
retrieving cpuid data, and updating microcode.
- Add cpucontrol(8) utility, that provides userland access to
the features of cpuctl(4).
- Add subsequent manpages.
The cpuctl(4) device operates as follows. The pseudo-device node cpuctlX
is created for each cpu present in the systems. The pseudo-device minor
number corresponds to the cpu number in the system. The cpuctl(4) pseudo-
device allows a number of ioctl to be preformed, namely RDMSR/WRMSR/CPUID
and UPDATE. The first pair alows the caller to read/write machine-specific
registers from the correspondent CPU. cpuid data could be retrieved using
the CPUID call, and microcode updates are applied via UPDATE.
The permissions are inforced based on the pseudo-device file permissions.
RDMSR/CPUID will be allowed when the caller has read access to the device
node, while WRMSR/UPDATE will be granted only when the node is opened
for writing. There're also a number of priv(9) checks.
The cpucontrol(8) utility is intened to provide userland access to
the cpuctl(4) device features. The utility also allows one to apply
cpu microcode updates.
Currently only Intel and AMD cpus are supported and were tested.
Approved by: kib
Reviewed by: rpaulo, cokane, Peter Jeremy
MFC after: 1 month
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/support.S | 44 | ||||
-rw-r--r-- | sys/amd64/conf/NOTES | 6 | ||||
-rw-r--r-- | sys/amd64/include/cpufunc.h | 5 | ||||
-rw-r--r-- | sys/amd64/include/specialreg.h | 7 |
4 files changed, 62 insertions, 0 deletions
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 2f2a3f1..35f5920 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -716,3 +716,47 @@ NON_GPROF_ENTRY(__bb_init_func) movq %rax,32(%rdi) movq %rdi,bbhead NON_GPROF_RET + +/* + * Support for reading MSRs in the safe manner. + */ +ENTRY(rdmsr_safe) +/* int rdmsr_safe(u_int msr, uint64_t *data) */ + movq PCPU(CURPCB),%r8 + movq $msr_onfault,PCB_ONFAULT(%r8) + movl %edi,%ecx + rdmsr /* Read MSR pointed by %ecx. Returns + hi byte in edx, lo in %eax */ + salq $32,%rdx /* sign-shift %rdx left */ + cltq /* sign-extend %eax -> %rax */ + orq %rdx,%rax + movq %rax,(%rsi) + xorq %rax,%rax + movq %rax,PCB_ONFAULT(%r8) + ret + +/* + * Support for writing MSRs in the safe manner. + */ +ENTRY(wrmsr_safe) +/* int wrmsr_safe(u_int msr, uint64_t data) */ + movq PCPU(CURPCB),%r8 + movq $msr_onfault,PCB_ONFAULT(%r8) + movl %edi,%ecx + movl %esi,%eax + sarq $32,%rsi + movl %esi,%edx + wrmsr /* Write MSR pointed by %ecx. Accepts + hi byte in edx, lo in %eax. */ + xorq %rax,%rax + movq %rax,PCB_ONFAULT(%r8) + ret + +/* + * MSR operations fault handler + */ + ALIGN_TEXT +msr_onfault: + movq $0,PCB_ONFAULT(%r8) + movl $EFAULT,%eax + ret diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index 1e0aae1..ac3cc42 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -401,6 +401,12 @@ device coretemp device k8temp # +# CPU control pseudo-device. Provides access to MSRs, CPUID info and +# microcode update feature. +# +device cpuctl + +# # System Management Bus (SMB) # options ENABLE_ALART # Control alarm on Intel intpm driver diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index ac0db87..a4a84b7 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -790,4 +790,9 @@ void wrmsr(u_int msr, u_int64_t newval); void reset_dbregs(void); +#ifdef _KERNEL +int rdmsr_safe(u_int msr, uint64_t *val); +int wrmsr_safe(u_int msr, uint64_t newval); +#endif + #endif /* !_MACHINE_CPUFUNC_H_ */ diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h index 760d2c5..4fd32ae 100644 --- a/sys/amd64/include/specialreg.h +++ b/sys/amd64/include/specialreg.h @@ -166,6 +166,12 @@ #define AMDID_CMP_CORES 0x000000ff /* + * CPUID manufacturers identifiers + */ +#define INTEL_VENDOR_ID "GenuineIntel" +#define AMD_VENDOR_ID "AuthenticAMD" + +/* * Model-specific registers for the i386 family */ #define MSR_P5_MC_ADDR 0x000 @@ -414,5 +420,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 /* !_MACHINE_SPECIALREG_H_ */ |