Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / misc / test_vm / src / geekos / idt.c
1 /*
2  * GeekOS IDT initialization code
3  * Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
4  * $Revision: 1.1 $
5  * 
6  * This is free software.  You are permitted to use,
7  * redistribute, and modify it as specified in the file "COPYING".
8  */
9
10 #include <geekos/kassert.h>
11 #include <geekos/defs.h>
12 #include <geekos/idt.h>
13 #include <geekos/serial.h>
14
15 /* ----------------------------------------------------------------------
16  * Private data and functions
17  * ---------------------------------------------------------------------- */
18
19 /*
20  * Allocated
21  */
22 static union IDT_Descriptor s_IDT[ NUM_IDT_ENTRIES ];
23
24 // JRL: why??? Should just call Alloc_Page(), otherwise we have dependencies all over the place
25 //static union IDT_Descriptor *s_IDT = (union IDT_Descriptor *)IDT_LOCATION;
26
27 /*
28  * These symbols are defined in lowlevel.asm, and define the
29  * size of the interrupt entry point table and the sizes
30  * of the individual entry points.  This gives us sufficient
31  * information to build the IDT.
32  */
33 extern char g_entryPointTableStart, g_entryPointTableEnd;
34 extern int g_handlerSizeNoErr, g_handlerSizeErr;
35
36 /*
37  * Table of C interrupt handler functions.
38  * Note that this is public only because it is used
39  * in lowlevel.asm.  Other code should not refer to it.
40  */
41 Interrupt_Handler g_interruptTable[ NUM_IDT_ENTRIES ];
42
43
44
45 void DumpIDT()
46 {
47   int i;
48   Print("IDT Contents:\n");
49
50   for (i=0;i<NUM_IDT_ENTRIES/16;i++) { 
51     if (s_IDT[i].ig.present) { 
52       Print("%d: segmentselector=%u, offset=%u, offsetLow=%u, segmentSelector=%u, reserved=%u, signature=%u, dpl=%u, present=%u, offsetHigh=%u\n",
53             i,
54             s_IDT[i].ig.segmentSelector,
55             (s_IDT[i].ig.offsetHigh<<16) + s_IDT[i].ig.offsetLow,
56             s_IDT[i].ig.offsetLow,
57             s_IDT[i].ig.segmentSelector,
58             s_IDT[i].ig.reserved,
59             s_IDT[i].ig.signature,
60             s_IDT[i].ig.dpl,
61             s_IDT[i].ig.present,
62             s_IDT[i].ig.offsetHigh);
63     }
64   }
65 }
66
67
68 void SerialDumpIDT()
69 {
70   int i;
71   SerialPrint("IDT Contents:\n");
72
73   for (i=0;i<NUM_IDT_ENTRIES;i++) { 
74     if (s_IDT[i].ig.present) { 
75       SerialPrint("%d: segmentselector=%u, offset=%u, offsetLow=%u, segmentSelector=%u, reserved=%u, signature=%u, dpl=%u, present=%u, offsetHigh=%u\n",
76             i,
77             s_IDT[i].ig.segmentSelector,
78             (s_IDT[i].ig.offsetHigh<<16) + s_IDT[i].ig.offsetLow,
79             s_IDT[i].ig.offsetLow,
80             s_IDT[i].ig.segmentSelector,
81             s_IDT[i].ig.reserved,
82             s_IDT[i].ig.signature,
83             s_IDT[i].ig.dpl,
84             s_IDT[i].ig.present,
85             s_IDT[i].ig.offsetHigh);
86       SerialPrint("\n");
87     }
88   }
89 }
90
91
92
93 /* ----------------------------------------------------------------------
94  * Public functions
95  * ---------------------------------------------------------------------- */
96
97 /*
98  * Initialize the Interrupt Descriptor Table.
99  * This will allow us to install C handler functions
100  * for interrupts, both processor-generated and
101  * those generated by external hardware.
102  */
103 void Init_IDT(void)
104 {
105     int i;
106     ushort_t limitAndBase[3];
107     ulong_t idtBaseAddr = (ulong_t) s_IDT;
108     ulong_t tableBaseAddr = (ulong_t) &g_entryPointTableStart;
109     ulong_t addr;
110
111     PrintBoth("Initializing IDT\n");
112
113     /* Make sure the layout of the entry point table is as we expect. */
114     KASSERT(g_handlerSizeNoErr == g_handlerSizeErr);
115     KASSERT((&g_entryPointTableEnd - &g_entryPointTableStart) ==
116              g_handlerSizeNoErr * NUM_IDT_ENTRIES);
117
118     /*
119      * Build the IDT.
120      * We're taking advantage of the fact that all of the
121      * entry points are laid out consecutively, and that they
122      * are all padded to be the same size.
123      */
124     for (i = 0, addr = tableBaseAddr; i < NUM_IDT_ENTRIES; ++i) {
125         /*
126          * All interrupts except for the syscall interrupt
127          * must have kernel privilege to access.
128          */
129         int dpl = (i == SYSCALL_INT) ? USER_PRIVILEGE : KERNEL_PRIVILEGE;
130         Init_Interrupt_Gate(&s_IDT[i], addr, dpl);
131         addr += g_handlerSizeNoErr;
132     }
133
134     /*
135      * Cruft together a 16 bit limit and 32 bit base address
136      * to load into the IDTR.
137      */
138     limitAndBase[0] = 8 * NUM_IDT_ENTRIES;
139     limitAndBase[1] = idtBaseAddr & 0xffff;
140     limitAndBase[2] = idtBaseAddr >> 16;
141
142     /* Install the new table in the IDTR. */
143     Load_IDTR(limitAndBase);
144 }
145
146 /*
147  * Initialize an interrupt gate with given handler address
148  * and descriptor privilege level.
149  */
150 void Init_Interrupt_Gate(union IDT_Descriptor* desc, ulong_t addr,
151         int dpl)
152 {
153     desc->ig.offsetLow = addr & 0xffff;
154     desc->ig.segmentSelector = KERNEL_CS;
155     desc->ig.reserved = 0;
156     desc->ig.signature = 0x70;  /* == 01110000b */
157     desc->ig.dpl = dpl;
158     desc->ig.present = 1;
159     desc->ig.offsetHigh = addr >> 16;
160 }
161
162 /*
163  * Install a C handler function for given interrupt.
164  * This is a lower-level notion than an "IRQ", which specifically
165  * means an interrupt triggered by external hardware.
166  * This function can install a handler for ANY interrupt.
167  */
168 void Install_Interrupt_Handler(int interrupt, Interrupt_Handler handler)
169 {
170     KASSERT(interrupt >= 0 && interrupt < NUM_IDT_ENTRIES);
171     g_interruptTable[interrupt] = handler;
172 }