sys/pic: Reinitialise PICs in pic_flush() to clear stale IRR/ISR state
This commit is contained in:
@@ -36,7 +36,7 @@ int irq_flush_type = IRQ_NO_FLUSH;
|
||||
void flush_irqs(void) {
|
||||
switch (irq_flush_type) {
|
||||
case IRQ_PIC_ONLY_FLUSH:
|
||||
pic_flush();
|
||||
pic_flush(0x08, 0x70);
|
||||
// FALLTHRU
|
||||
case IRQ_NO_FLUSH:
|
||||
return;
|
||||
@@ -56,7 +56,7 @@ void flush_irqs(void) {
|
||||
asm volatile ("lidt %0" :: "m"(new_idt) : "memory");
|
||||
|
||||
// Flush the legacy PIC so we know the remaining ints come from the LAPIC
|
||||
pic_flush();
|
||||
pic_flush(0x20, 0x28);
|
||||
|
||||
asm volatile ("sti" ::: "memory");
|
||||
|
||||
|
||||
@@ -15,10 +15,26 @@ void pic_eoi(int irq) {
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
|
||||
// Flush all potentially pending IRQs
|
||||
void pic_flush(void) {
|
||||
for (int i = 0; i < 16; i++)
|
||||
pic_eoi(i);
|
||||
// Flush all pending IRQs by reinitialising the PICs, preserving the IMR
|
||||
void pic_flush(uint8_t master_base, uint8_t slave_base) {
|
||||
uint8_t master_imr = inb(0x21);
|
||||
uint8_t slave_imr = inb(0xa1);
|
||||
|
||||
outb(0xa1, 0xff);
|
||||
outb(0x21, 0xff);
|
||||
|
||||
outb(0x20, 0x11);
|
||||
outb(0x21, master_base);
|
||||
outb(0x21, 0x04);
|
||||
outb(0x21, 0x01);
|
||||
|
||||
outb(0xa0, 0x11);
|
||||
outb(0xa1, slave_base);
|
||||
outb(0xa1, 0x02);
|
||||
outb(0xa1, 0x01);
|
||||
|
||||
outb(0xa1, slave_imr);
|
||||
outb(0x21, master_imr);
|
||||
}
|
||||
|
||||
void pic_set_mask(int line, bool status) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#ifndef SYS__PIC_H__
|
||||
#define SYS__PIC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void pic_eoi(int irq);
|
||||
void pic_flush(void);
|
||||
void pic_flush(uint8_t master_base, uint8_t slave_base);
|
||||
void pic_set_mask(int line, bool status);
|
||||
void pic_mask_all(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user