apic: serialize writes to x2apic MSR...

as required by the specifications (it isn't needed with memory mapped i/o).
This commit is contained in:
Jérôme Duval 2013-08-26 21:48:33 +02:00
parent 787773400c
commit 0edcbd2754
3 changed files with 19 additions and 4 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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
}