#pragma once #include "interrupt.h" #define save_flags(flags) asm volatile("pushfl ; popl %0" : "=g"(flags)::"memory") #define restore_flags(flags) asm volatile("push %0; popfl" ::"g"(flags) : "memory") #define disable_IRQs(flags) \ ({ \ save_flags(flags); \ asm("cli\n"); \ }) #define restore_IRQs(flags) restore_flags(flags) #define IRQ_TIMER 0 // MASTER IRQ #define IRQ_KEYBOARD 1 #define IRQ_SLAVE_PIC 2 #define IRQ_COM2 3 #define IRQ_COM1 4 #define IRQ_LPT2 5 #define IRQ_FLOPPY 6 #define IRQ_LPT1 7 #define IRQ_8_NOT_DEFINED 8 // SLAVE #define IRQ_RESERVED_1 9 // SLAVE IRQ #define IRQ_RESERVED_2 10 #define IRQ_RESERVED_3 11 #define IRQ_RESERVED_4 12 #define IRQ_COPROCESSOR 13 #define IRQ_HARDDISK 14 #define IRQ_RESERVED_5 15 #define IRQ_INTERRUPT_BASE_ADDRESS 0x20 #define IRQ_NUM 16 // An handler should finish by the iret opcode -> https://wiki.osdev.org/Interrupt_Service_Routines // That's why we use wrapper around them or the gcc interrupt attribut // __attribute__((interrupt)) void (*irq_handler)(int irq); typedef void (*irq_handler)(struct interrupt_frame *frame); int irqSetup(); int irqSetRoutine(int irq, irq_handler handler);