From 0edcbd2754bbde71864f6ec2578a05084d4dc23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Mon, 26 Aug 2013 21:48:33 +0200 Subject: [PATCH] apic: serialize writes to x2apic MSR... as required by the specifications (it isn't needed with memory mapped i/o). --- headers/private/kernel/arch/cpu.h | 1 + src/system/kernel/arch/x86/apic.cpp | 9 ++++++--- src/system/kernel/arch/x86/arch_cpu.cpp | 13 ++++++++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/headers/private/kernel/arch/cpu.h b/headers/private/kernel/arch/cpu.h index 4bc77487c7..e1bf1fdb5e 100644 --- a/headers/private/kernel/arch/cpu.h +++ b/headers/private/kernel/arch/cpu.h @@ -46,6 +46,7 @@ void arch_cpu_sync_icache(void *address, size_t length); void arch_cpu_memory_read_barrier(void); void arch_cpu_memory_write_barrier(void); +void arch_cpu_memory_read_write_barrier(void); #ifdef __cplusplus diff --git a/src/system/kernel/arch/x86/apic.cpp b/src/system/kernel/arch/x86/apic.cpp index d8a653a1dd..47587063a3 100644 --- a/src/system/kernel/arch/x86/apic.cpp +++ b/src/system/kernel/arch/x86/apic.cpp @@ -142,8 +142,10 @@ void apic_set_intr_command_1(uint32 config) { if (sX2APIC) { + uint64 value = x86_read_msr(IA32_MSR_APIC_INTR_COMMAND); + arch_cpu_memory_read_write_barrier(); x86_write_msr(IA32_MSR_APIC_INTR_COMMAND, - (x86_read_msr(IA32_MSR_APIC_INTR_COMMAND) & 0xffffffff00000000LL) | config); + (value & 0xffffffff00000000LL) | config); } else apic_write(APIC_INTR_COMMAND_1, config); } @@ -163,9 +165,10 @@ void apic_set_intr_command_2(uint32 config) { if (sX2APIC) { + uint64 value = x86_read_msr(IA32_MSR_APIC_INTR_COMMAND); + arch_cpu_memory_read_write_barrier(); x86_write_msr(IA32_MSR_APIC_INTR_COMMAND, - (x86_read_msr(IA32_MSR_APIC_INTR_COMMAND) & 0xffffffff) - | ((uint64)config << 32)); + (value & 0xffffffff) | ((uint64)config << 32)); } else apic_write(APIC_INTR_COMMAND_2, config); } diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 710307b3a2..67212e2e17 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -523,7 +523,7 @@ detect_cpu(int currentCPU) // print some fun data get_current_cpuid(&cpuid, 0); - uint32 maxBasicLeaf = cpuid.eax_0.max_eax; + uint32 maxBasicLeaf = cpuid.eax_0.max_eax; // build the vendor string memset(vendorString, 0, sizeof(vendorString)); @@ -1017,3 +1017,14 @@ arch_cpu_memory_write_barrier(void) #endif } + +void +arch_cpu_memory_read_write_barrier(void) +{ +#ifdef __x86_64__ + asm volatile("mfence" : : : "memory"); +#else + asm volatile ("lock;" : : : "memory"); + asm volatile ("addl $0, 0(%%esp);" : : : "memory"); +#endif +}