From 3cd49007954e8d6d2439c238ce7a6df44da281b0 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Mon, 1 Jul 2024 14:29:46 -0400 Subject: [PATCH] kernel/x86: Do not read APIC registers while setting the interrupt command. FreeBSD's equivalent routine (lapic_write_icr) does not read these registers; in fact the only thing that does read them are its initialzation routines, and then its code to check the interrupt delivery status (same as we do.) Additionally, APIC_INTR_COMMAND_1_MASK only contains the bits that are set by the OS, not the ones set by the APIC, which means that APIC_DELIVERY_STATUS (bit 12) isn't included and we are thus writing it back here, which doesn't seem correct. Change-Id: I2c74b7b8de3cd8295c8dd86e5a7c6530dc5648ed Reviewed-on: https://review.haiku-os.org/c/haiku/+/7827 Tested-by: Commit checker robot Haiku-Format: Haiku-format Bot Reviewed-by: waddlesplash --- src/system/kernel/arch/x86/apic.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/system/kernel/arch/x86/apic.cpp b/src/system/kernel/arch/x86/apic.cpp index 5b220f25ad..d8d5559f36 100644 --- a/src/system/kernel/arch/x86/apic.cpp +++ b/src/system/kernel/arch/x86/apic.cpp @@ -151,20 +151,16 @@ void apic_set_interrupt_command(uint32 destination, uint32 mode) { if (sX2APIC) { - uint64 command = x86_read_msr(IA32_MSR_APIC_INTR_COMMAND); - command &= APIC_INTR_COMMAND_1_MASK; + uint64 command = 0; command |= (uint64)destination << 32; command |= mode; x86_write_msr(IA32_MSR_APIC_INTR_COMMAND, command); } else { - uint32 command2 = apic_read(APIC_INTR_COMMAND_2) - & APIC_INTR_COMMAND_2_MASK; + uint32 command2 = 0; command2 |= destination << 24; apic_write(APIC_INTR_COMMAND_2, command2); - uint32 command1 = apic_read(APIC_INTR_COMMAND_1) - & APIC_INTR_COMMAND_1_MASK; - command1 |= mode; + uint32 command1 = mode; apic_write(APIC_INTR_COMMAND_1, command1); } }