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
|
#ifndef int_header
#define int_header
#include <stdint.h>
#include <stddef.h>
void usleep(unsigned int us);
void init_interrupts();
typedef uint32_t *lapic_t;
//this is only for madt; do we really need it here?
struct ioapic_t {
void *address;
unsigned int gsi_base;
unsigned int gsi_count;
};
//future: if we start to do things like this more then once,
struct ioapic_fixedlen {
size_t count;
struct ioapic_t *ioapic;
};
//TODO change name
struct apic_vt {
uint8_t vector;
unsigned int delivery_mode:3;
unsigned int dest_mode:1;
unsigned int delivery_status:1;
unsigned int polarity:1; //0 = high, 1 = low.
unsigned int remote_irr:1;
unsigned int trigger_mode:1;
unsigned int mask:1;
unsigned long int reserved:40;
unsigned int destination:7;
} __attribute__((packed));
//simplified idt_descriptor makes things easier
struct idt_entry {
void *addr;
unsigned int ist:3;
unsigned int type:4;
unsigned int priv:2;
};
#define IOAPIC_REDIRECT_FIXED(vector, destination) \
((struct apic_vt) { \
.vector = vector, \
.delivery_mode = 0, \
.dest_mode = 0, \
.polarity = 0, \
.remote_irr = 0, \
.trigger_mode = 0, \
.mask = 0, \
.destination = destination \
})
#define KERNEL_IDT_GATE(isr) \
((struct idt_entry) { \
.addr = isr, \
.ist = 0, \
.type = INT_GATE_64, \
.priv = 0 \
})
#define TASK_GATE_64 0x5
#define INT_GATE_64 0xe
#define TRAP_GATE_64 0xf
#define SPURRIOUS_VECTOR 255
void create_fixed_interrupt(unsigned int irq, struct apic_vt *redirect);
void clear_int();
unsigned int alloc_idt(struct idt_entry *entry);
void free_idt(unsigned int entry);
void modify_idt(struct idt_entry *entry, unsigned int vector);
#endif
|