matos/arch/x86/irq.h
2021-10-08 15:30:08 +02:00

45 lines
1.7 KiB
C

#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 cpu_state *frame);
typedef void (*native_irq_handler)(struct interrupt_frame *frame);
int irqSetup();
// For C coded handler (The interrupt specific part is managed by a wrapper)
int irqSetRoutineWrapped(int irq, irq_handler handler);
// For ASM handler taking care of the special instruction needed by an IRQ handler
int irqSetRoutine(int irq, native_irq_handler handler);