aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/include/idt.h
blob: 45cc3e35a3cad6bbff2f7f966aeee1ba6352d91d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#pragma once

/*	The IDT is the system descriptor table that tells the CPU what to do when an interrupt fires.
	There are three categories of interrupts :
	- Exceptions ; eg page fault, divide by 0
	- IRQ : interrupts caused by hardware
	- System calls : when an applications asks the system to do something */

#include <config.h>

#define IRQ0  0			// PIT
#define IRQ1  1			// PCKBD
#define IRQ2  2			// not used
#define IRQ3  3			// COM2
#define IRQ4  4			// COM1
#define IRQ5  5			// LPT2
#define IRQ6  6			// Floppy
#define IRQ7  7			// LPT1
#define IRQ8  8			// CMOS RTC
#define IRQ9  9			// free -> PCI IRQ
#define IRQ10 10		// free -> PCI IRQ
#define IRQ11 11		// free -> PCI IRQ
#define IRQ12 12		// PS2 mouse
#define IRQ13 13		// FPU
#define IRQ14 14		// Primary ATA HD
#define IRQ15 15		// Secondary ATA HD

#define EX_DIVIDE_ERROR                  0         // No error code
#define EX_DEBUG                         1         // No error code
#define EX_NMI_INTERRUPT                 2         // No error code
#define EX_BREAKPOINT                    3         // No error code
#define EX_OVERFLOW                      4         // No error code
#define EX_BOUND_RANGE_EXCEDEED          5         // No error code
#define EX_INVALID_OPCODE                6         // No error code
#define EX_DEVICE_NOT_AVAILABLE          7         // No error code
#define EX_DOUBLE_FAULT                  8         // Yes (Zero)
#define EX_COPROCESSOR_SEGMENT_OVERRUN   9         // No error code
#define EX_INVALID_TSS                  10         // Yes
#define EX_SEGMENT_NOT_PRESENT          11         // Yes
#define EX_STACK_SEGMENT_FAULT          12         // Yes
#define EX_GENERAL_PROTECTION           13         // Yes
#define EX_PAGE_FAULT                   14         // Yes
#define EX_INTEL_RESERVED_1             15         // No
#define EX_FLOATING_POINT_ERROR         16         // No
#define EX_ALIGNEMENT_CHECK             17         // Yes (Zero)
#define EX_MACHINE_CHECK                18         // No
#define EX_INTEL_RESERVED_2             19         // No
#define EX_INTEL_RESERVED_3             20         // No
#define EX_INTEL_RESERVED_4             21         // No
#define EX_INTEL_RESERVED_5             22         // No
#define EX_INTEL_RESERVED_6             23         // No
#define EX_INTEL_RESERVED_7             24         // No
#define EX_INTEL_RESERVED_8             25         // No
#define EX_INTEL_RESERVED_9             26         // No
#define EX_INTEL_RESERVED_10            27         // No
#define EX_INTEL_RESERVED_11            28         // No
#define EX_INTEL_RESERVED_12            29         // No
#define EX_INTEL_RESERVED_13            30         // No
#define EX_INTEL_RESERVED_14            31         // No

#define EFLAGS_IF		(0x1 << 9)

typedef struct registers {
	uint32_t ds;                  // Data segment selector
	uint32_t edi, esi, ebp, useless_esp, ebx, edx, ecx, eax; // Pushed by pusha.
	uint32_t int_no, err_code;    // Interrupt number and error code (if applicable)
	uint32_t eip, cs, eflags, esp, ss; // Pushed by the processor automatically.
} registers_t;

typedef void (*isr_handler_t)(registers_t*);

void idt_init();

void idt_set_ex_handler(int number, isr_handler_t func);	//Set exception handler
void idt_set_irq_handler(int number, isr_handler_t func);	//Set IRQ handler

// Warning about IRQ handlers :
// IRQ handlers may run on the kernel0 stack, which is reset each time the scheduler
// is entered. Therefore IRQ handler routines may not call yield(), which makes them
// unable to use mutexes, memory allocation and most usefull things. Basically the only
// thing they can do is wake up another thread, so it is a good idea to have a thread
// that waits for the IRQ and does something when it happens, and the IRQ handler only
// wakes up that thread when the IRQ happens. They may also communicate via atomical
// or lock free data structures.

void dbg_dump_registers(registers_t*);

/* vim: set ts=4 sw=4 tw=0 noet :*/