hrev45992 adds 1 changeset to branch 'master' old head: 787773400ce9ee4ce71d9255e1be8fac66584615 new head: 0edcbd2754bbde71864f6ec2578a05084d4dc23d overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=0edcbd2+%5E7877734 ---------------------------------------------------------------------------- 0edcbd2: apic: serialize writes to x2apic MSR... as required by the specifications (it isn't needed with memory mapped i/o). [ Jérôme Duval <jerome.duval@xxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev45992 Commit: 0edcbd2754bbde71864f6ec2578a05084d4dc23d URL: http://cgit.haiku-os.org/haiku/commit/?id=0edcbd2 Author: Jérôme Duval <jerome.duval@xxxxxxxxx> Date: Mon Aug 26 19:48:33 2013 UTC ---------------------------------------------------------------------------- 3 files changed, 19 insertions(+), 4 deletions(-) headers/private/kernel/arch/cpu.h | 1 + src/system/kernel/arch/x86/apic.cpp | 9 ++++++--- src/system/kernel/arch/x86/arch_cpu.cpp | 13 ++++++++++++- ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/arch/cpu.h b/headers/private/kernel/arch/cpu.h index 4bc7748..e1bf1fd 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 d8a653a..4758706 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 710307b..67212e2 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 +}