aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/include
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2015-02-09 21:00:56 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2015-02-09 21:00:56 +0000
commit4c918926cd538a36bb2d54a0f4eb4ca3ebbe16e4 (patch)
treed2e88c87f150ce7e0dfe34e37fbc902c5f84fd8a /sys/amd64/include
parent2575fbb82713dcfca8a5a8794119a7cd4c713405 (diff)
downloadsrc-4c918926cd538a36bb2d54a0f4eb4ca3ebbe16e4.tar.gz
src-4c918926cd538a36bb2d54a0f4eb4ca3ebbe16e4.zip
Add x2APIC support. Enable it by default if CPU is capable. The
hw.x2apic_enable tunable allows disabling it from the loader prompt. To closely repeat effects of the uncached memory ops when accessing registers in the xAPIC mode, the x2APIC writes to MSRs are preceeded by mfence, except for the EOI notifications. This is probably too strict, only ICR writes to send IPI require serialization to ensure that other CPUs see the previous actions when IPI is delivered. This may be changed later. In vmm justreturn IPI handler, call doreti_iret instead of doing iretd inline, to handle corner conditions. Note that the patch only switches LAPICs into x2APIC mode. It does not enables FreeBSD to support > 255 CPUs, which requires parsing x2APIC MADT entries and doing interrupts remapping, but is the required step on the way. Reviewed by: neel Tested by: pho (real hardware), neel (on bhyve) Discussed with: jhb, grehan Sponsored by: The FreeBSD Foundation MFC after: 2 months
Notes
Notes: svn path=/head/; revision=278473
Diffstat (limited to 'sys/amd64/include')
-rw-r--r--sys/amd64/include/cpufunc.h10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index 7464739cf43d..7ea4bcf48850 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -343,6 +343,15 @@ rdmsr(u_int msr)
return (low | ((uint64_t)high << 32));
}
+static __inline uint32_t
+rdmsr32(u_int msr)
+{
+ uint32_t low;
+
+ __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "rdx");
+ return (low);
+}
+
static __inline uint64_t
rdpmc(u_int pmc)
{
@@ -826,6 +835,7 @@ u_long rcr2(void);
u_long rcr3(void);
u_long rcr4(void);
uint64_t rdmsr(u_int msr);
+uint32_t rdmsr32(u_int msr);
uint64_t rdpmc(u_int pmc);
uint64_t rdr0(void);
uint64_t rdr1(void);