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:
@@ -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_read_barrier(void);
|
||||||
void arch_cpu_memory_write_barrier(void);
|
void arch_cpu_memory_write_barrier(void);
|
||||||
|
void arch_cpu_memory_read_write_barrier(void);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -142,8 +142,10 @@ void
|
|||||||
apic_set_intr_command_1(uint32 config)
|
apic_set_intr_command_1(uint32 config)
|
||||||
{
|
{
|
||||||
if (sX2APIC) {
|
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_write_msr(IA32_MSR_APIC_INTR_COMMAND,
|
||||||
(x86_read_msr(IA32_MSR_APIC_INTR_COMMAND) & 0xffffffff00000000LL) | config);
|
(value & 0xffffffff00000000LL) | config);
|
||||||
} else
|
} else
|
||||||
apic_write(APIC_INTR_COMMAND_1, config);
|
apic_write(APIC_INTR_COMMAND_1, config);
|
||||||
}
|
}
|
||||||
@@ -163,9 +165,10 @@ void
|
|||||||
apic_set_intr_command_2(uint32 config)
|
apic_set_intr_command_2(uint32 config)
|
||||||
{
|
{
|
||||||
if (sX2APIC) {
|
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_write_msr(IA32_MSR_APIC_INTR_COMMAND,
|
||||||
(x86_read_msr(IA32_MSR_APIC_INTR_COMMAND) & 0xffffffff)
|
(value & 0xffffffff) | ((uint64)config << 32));
|
||||||
| ((uint64)config << 32));
|
|
||||||
} else
|
} else
|
||||||
apic_write(APIC_INTR_COMMAND_2, config);
|
apic_write(APIC_INTR_COMMAND_2, config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ detect_cpu(int currentCPU)
|
|||||||
|
|
||||||
// print some fun data
|
// print some fun data
|
||||||
get_current_cpuid(&cpuid, 0);
|
get_current_cpuid(&cpuid, 0);
|
||||||
uint32 maxBasicLeaf = cpuid.eax_0.max_eax;
|
uint32 maxBasicLeaf = cpuid.eax_0.max_eax;
|
||||||
|
|
||||||
// build the vendor string
|
// build the vendor string
|
||||||
memset(vendorString, 0, sizeof(vendorString));
|
memset(vendorString, 0, sizeof(vendorString));
|
||||||
@@ -1017,3 +1017,14 @@ arch_cpu_memory_write_barrier(void)
|
|||||||
#endif
|
#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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user