blob: 3aa5a1e7846fd4380f51562f67970d22f8fe57c3 (
plain)
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
|
#pragma once
#include <types.h>
class IDT {
public:
struct Pointer {
uint16_t limit;
uint32_t base;
} __attribute__((packed));
enum InterruptType : uint8_t {
Null = 0,
InterruptGate = 0b110, // hardware interrupts are disabled while the handler runs
TrapGate = 0b111, // hardware interrupts remain active while the handler runs
TaskGate = 0b101, // selector points to TSS rather than a code segment
};
class Entry {
public:
Entry(uint32_t offset = 0, uint16_t select = 0, InterruptType t = Null) {
offset_0_15 = offset & 0xffff;
offset_16_31 = (offset & 0xffff0000) >> 16;
selector = select;
type = t;
}
private:
uint16_t offset_0_15; // 0-15 offset in the segment
uint16_t selector; // 16-31 selector of the code segment
[[maybe_unused]] uint8_t null = 0; // 32-39 unused in protected mode
InterruptType type : 3; // 40-42 type
[[maybe_unused]] bool d : 1 = true; // 43 true: 32-bit, false: 16-bit segment
[[maybe_unused]] uint8_t u : 1 = 0; // 44 unused
uint8_t dpl : 2 = 0; // 45-46 descriptor privilege level
[[maybe_unused]] bool e : 1 = true; // 47 enable
uint16_t offset_16_31; // 48-63 offset high
} __attribute__((packed));
IDT();
private:
Entry table[256];
};
struct interrupt_frame {
uword_t ip;
uword_t cs;
uword_t flags;
uword_t sp;
uword_t ss;
};
/* https://wiki.osdev.org/Interrupt_Service_Routines */
template <uint8_t irq>
__attribute__((interrupt)) void kirq(interrupt_frame* frame);
template <>
void kirq<0x0>(interrupt_frame* frame);
template <>
void kirq<0x1>(interrupt_frame* frame);
|