diff options
author | Danny Holman <dholman@gymli.xyz> | 2021-09-28 09:04:01 -0500 |
---|---|---|
committer | Danny Holman <dholman@gymli.xyz> | 2021-09-28 09:04:38 -0500 |
commit | 0ad50c878838640ce53c202ab028d7b2c5810fe6 (patch) | |
tree | 77f189f1369a31b1941dfc5cacb8da71fe343aca /arch/i386/boot/pic.c | |
parent | 7bf2c634fdb55d67affe74a2ed0a157610308942 (diff) |
arch: i386: add support for 8259 PIC
Add support for the 8259 programmable interrupt controller.
Signed-off-by: Danny Holman <dholman@gymli.xyz>
Diffstat (limited to 'arch/i386/boot/pic.c')
-rw-r--r-- | arch/i386/boot/pic.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/arch/i386/boot/pic.c b/arch/i386/boot/pic.c new file mode 100644 index 0000000..f103b92 --- /dev/null +++ b/arch/i386/boot/pic.c @@ -0,0 +1,53 @@ +#include <kernel/pic.h> + +void pic_eoi(unsigned char irq) { + if (irq >= 8) + outb(PIC2_COMMAND, 0x20); + outb(PIC1_COMMAND, 0x20); +} + +void pic_remap(void) { + unsigned char a1 = inb(PIC1_DATA); + unsigned char a2 = inb(PIC2_DATA); + + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + outb(PIC1_DATA, PIC1); + outb(PIC2_DATA, PIC2); + outb(PIC1_DATA, 4); + outb(PIC2_DATA, 2); + outb(PIC1_DATA, ICW4_8086); + outb(PIC2_DATA, ICW4_8086); + outb(PIC1_DATA, a1); + outb(PIC2_DATA, a2); +} + +void irq_set_mask(uint8_t irq) { + uint16_t port; + uint8_t data; + + if (irq < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + irq -= 8; + } + + data = inb(port) | (1 << irq); + outb(port, data); +} + +void irq_clear_mask(unsigned char irq) { + uint16_t port; + uint8_t data; + + if (irq < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + irq -= 8; + } + + data = inb(port) & ~(1 << irq); + outb(port, data); +} |