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:
committed by
waddlesplash
parent
3ea2ee1a40
commit
3cd4900795
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user