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 <[email protected]>
Haiku-Format: Haiku-format Bot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2024-07-09 17:52:19 +00:00
committed by waddlesplash
parent 3ea2ee1a40
commit 3cd4900795
+3 -7
View File
@@ -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);
}
}