Nothing
[ZeXOS.git] / kernel / idt.c
blob14920103477a53a48d72f49c1ca747aaee107e8c
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <system.h>
21 #include <x86.h>
22 #include <string.h>
24 /* Defines an IDT entry */
25 struct idt_entry
27 unsigned short base_lo;
28 unsigned short sel;
29 unsigned char always0;
30 unsigned char flags;
31 unsigned short base_hi;
32 } __attribute__((packed));
34 struct idt_ptr
36 unsigned short limit;
37 unsigned int base;
38 } __attribute__((packed));
40 /* Declare an IDT of 256 entries. Although we will only use the
41 * first 32 entries in this tutorial, the rest exists as a bit
42 * of a trap. If any undefined IDT entry is hit, it normally
43 * will cause an "Unhandled Interrupt" exception. Any descriptor
44 * for which the 'presence' bit is cleared (0) will generate an
45 * "Unhandled Interrupt" exception */
46 struct idt_entry idt[256];
47 struct idt_ptr idtp;
49 /* This exists in 'start.asm', and is used to load our IDT */
50 extern void idt_load();
52 #define set_intr_gate(n,addr) \
53 _set_gate(&idt[n],14,0,addr)
55 #define set_trap_gate(n,addr) \
56 _set_gate(&idt[n],15,0,addr)
58 #define set_system_gate(n,addr) \
59 _set_gate(&idt[n],15,3,addr)
61 /* Use this function to set an entry in the IDT. Alot simpler
62 * than twiddling with the GDT ;) */
63 void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
65 /* The interrupt routine's base address */
66 idt[num].base_lo = (base & 0xFFFF);
67 idt[num].base_hi = (base >> 16) & 0xFFFF;
69 /* The segment or 'selector' that this IDT entry will use
70 * is set here, along with any access flags */
71 idt[num].sel = sel;
72 idt[num].always0 = 0;
73 idt[num].flags = flags;
76 extern int system_call (void);
78 /* Installs the IDT */
79 unsigned int idt_install ()
81 /* Sets the special IDT pointer up, just like in 'gdt.c' */
82 idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
83 idtp.base = &idt;
85 /* Clear out the entire IDT, initializing it to zeros */
86 memset(&idt, 0, sizeof(struct idt_entry) * 256);
88 /* Add any new ISRs to the IDT here using idt_set_gate */
90 /* Points the processor's internal register to the new IDT */
91 idt_load ();
93 set_system_gate(0x80, &system_call);
95 return 1;