3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 /* Defines an IDT entry */
28 unsigned short base_lo
;
30 unsigned char always0
;
32 unsigned short base_hi
;
33 } __attribute__((packed
));
39 } __attribute__((packed
));
41 /* Declare an IDT of 256 entries. Although we will only use the
42 * first 32 entries in this tutorial, the rest exists as a bit
43 * of a trap. If any undefined IDT entry is hit, it normally
44 * will cause an "Unhandled Interrupt" exception. Any descriptor
45 * for which the 'presence' bit is cleared (0) will generate an
46 * "Unhandled Interrupt" exception */
47 struct idt_entry idt
[256];
50 /* This exists in 'start.asm', and is used to load our IDT */
51 extern void idt_load();
53 #define set_intr_gate(n,addr) \
54 _set_gate(&idt[n],14,0,addr)
56 #define set_trap_gate(n,addr) \
57 _set_gate(&idt[n],15,0,addr)
59 #define set_system_gate(n,addr) \
60 _set_gate(&idt[n],15,3,addr)
62 /* Use this function to set an entry in the IDT. Alot simpler
63 * than twiddling with the GDT ;) */
64 void idt_set_gate(unsigned char num
, unsigned long base
, unsigned short sel
, unsigned char flags
)
66 /* The interrupt routine's base address */
67 idt
[num
].base_lo
= (base
& 0xFFFF);
68 idt
[num
].base_hi
= (base
>> 16) & 0xFFFF;
70 /* The segment or 'selector' that this IDT entry will use
71 * is set here, along with any access flags */
74 idt
[num
].flags
= flags
;
77 extern int system_call (void);
79 /* Installs the IDT */
80 unsigned int idt_install ()
82 /* Sets the special IDT pointer up, just like in 'gdt.c' */
83 idtp
.limit
= (sizeof (struct idt_entry
) * 256) - 1;
84 idtp
.base
= (unsigned int) &idt
;
86 /* Clear out the entire IDT, initializing it to zeros */
87 memset(&idt
, 0, sizeof(struct idt_entry
) * 256);
89 /* Add any new ISRs to the IDT here using idt_set_gate */
91 /* Points the processor's internal register to the new IDT */
94 set_system_gate (0x80, &system_call
);