COBE 0.1 ALPHA
|
00001 #include <stdio.h> 00002 #include <idt.h> 00003 #include <keyboard.h> 00004 #include <pic.h> 00005 #include <multitasking.h> 00006 #include <cmos.h> 00007 #include <stdint.h> 00008 #include <panic.h> 00009 #include <syscalls.h> 00010 #include <pgng.h> 00011 #include <fdc.h> 00012 00013 extern void interrupt_0(void); 00014 extern void interrupt_1(void); 00015 extern void interrupt_2(void); 00016 extern void interrupt_3(void); 00017 extern void interrupt_4(void); 00018 extern void interrupt_5(void); 00019 extern void interrupt_6(void); 00020 extern void interrupt_7(void); 00021 extern void interrupt_error_8(void); 00022 extern void interrupt_9(void); 00023 extern void interrupt_error_10(void); 00024 extern void interrupt_error_11(void); 00025 extern void interrupt_error_12(void); 00026 extern void interrupt_error_13(void); 00027 extern void interrupt_error_14(void); 00028 extern void interrupt_16(void); 00029 extern void interrupt_error_17(void); 00030 extern void interrupt_18(void); 00031 extern void interrupt_19(void); 00032 00033 extern void interrupt_32(void); 00034 extern void interrupt_33(void); 00035 extern void interrupt_34(void); 00036 extern void interrupt_35(void); 00037 extern void interrupt_36(void); 00038 extern void interrupt_37(void); 00039 extern void interrupt_38(void); 00040 extern void interrupt_39(void); 00041 extern void interrupt_40(void); 00042 extern void interrupt_41(void); 00043 extern void interrupt_42(void); 00044 extern void interrupt_43(void); 00045 extern void interrupt_44(void); 00046 extern void interrupt_45(void); 00047 extern void interrupt_46(void); 00048 extern void interrupt_47(void); 00049 00050 extern void interrupt_48(void); 00051 extern new_tss_t tss; 00052 extern new_task_t* current_task; 00053 extern struct paging_directory* kernel_map; 00054 extern uint8_t booted; 00055 00056 idt_entry_t idt[256]; 00057 idt_ptr_t idt_ptr; 00058 00060 00061 00062 void init_idt() { 00063 00064 idt_ptr.limit = (sizeof(struct idt_entry_struct) * 256 ) -1; //----------Das IDT-Limit und die Base-Addresse der IDT werden in die Struktur eingetragen---------- 00065 idt_ptr.base = (int)&idt; 00066 00067 kmemset(&idt, 0, sizeof(struct idt_entry_struct) * 256); //----------Die IDT Tabelle wird mit 0en belegt---------- 00068 00069 //----------Die Interrupts werden in die IDT eingetragen---------- 00070 set_idt(0, interrupt_0, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00071 set_idt(1, interrupt_1, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00072 set_idt(2, interrupt_2, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00073 set_idt(3, interrupt_3, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00074 set_idt(4, interrupt_4, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00075 set_idt(5, interrupt_5, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00076 set_idt(6, interrupt_6, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00077 set_idt(7, interrupt_7, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00078 set_idt(8, interrupt_error_8, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00079 set_idt(9, interrupt_9, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00080 set_idt(10, interrupt_error_10, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00081 set_idt(11, interrupt_error_11, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00082 set_idt(12, interrupt_error_12, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00083 set_idt(13, interrupt_error_13, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00084 set_idt(14, interrupt_error_14, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00085 set_idt(16, interrupt_16, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00086 set_idt(17, interrupt_error_17, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00087 set_idt(18, interrupt_18, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00088 set_idt(19, interrupt_19, 0x8, ITR_GATE | RING0 | PRESENT_BIT); 00089 00090 set_idt(32, interrupt_32, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 0 00091 set_idt(33, interrupt_33, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 1 00092 set_idt(34, interrupt_34, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 2 00093 set_idt(35, interrupt_35, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 3 00094 set_idt(36, interrupt_36, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 4 00095 set_idt(37, interrupt_37, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 5 00096 set_idt(38, interrupt_38, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 6 00097 set_idt(39, interrupt_39, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 7 00098 set_idt(40, interrupt_40, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 8 00099 set_idt(41, interrupt_41, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 9 00100 set_idt(42, interrupt_42, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 10 00101 set_idt(43, interrupt_43, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 11 00102 set_idt(44, interrupt_44, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 12 00103 set_idt(45, interrupt_45, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 13 00104 set_idt(46, interrupt_46, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 14 00105 set_idt(47, interrupt_47, 0x8, ITR_GATE | RING0 | PRESENT_BIT); //IRQ 15 00106 00107 set_idt(48, interrupt_48, 0x8, ITR_GATE | RING3 | PRESENT_BIT); 00108 00109 __asm("lidt (idt_ptr)"); //----------Der Pointer auf die IDT wird in das IDT Register geladen---------- 00110 pic_mask_irqs(0x08); //----------Der CMOS-IRQ wird maskiert---------- 00111 return; 00112 } 00113 00115 00116 void set_idt(uint8_t num, void (*interrupt)(), uint16_t sel, uint8_t flags) { 00117 00118 //----------Die Basis-Addresse ist der Ort an dem der Interrupt liegt, die Addresse wird in Offsets aufgeteilt---------- 00119 uint32_t base = (uint32_t) interrupt; 00120 idt[num].offset_1 = (base & 0xFFFF); 00121 idt[num].offset_2 = (base >> 16) & 0xFFFF; 00122 idt[num].selector = sel; //----------Gibt den Selektor an, in dem CS bei diesem Interrupt gewechselt wird, 0x8 steht für RING0---------- 00123 idt[num].zero = 0; //----------Im 32-Bit muss dieser Wert 0 sein, nur für 64-Bit wichtig!---------- 00124 idt[num].typ_attr = flags; //----------Die Flags des Interrupts werden gesetzt---------- 00125 return; 00126 } 00127 00129 00130 cpu_regs* itr_handler(cpu_regs *registers) { 00131 00132 cpu_regs* new_cpu_status = registers; 00133 00134 switch(new_cpu_status->interrupt) 00135 { 00136 00137 //----------Bei Exceptions wird die Kernel-Panic Funktion aufgerufen---------- 00138 case 0x00: //INTR 0 00139 kernel_panic(0, new_cpu_status); 00140 break; 00141 00142 case 0x01: //INTR 1 00143 kernel_panic(0, new_cpu_status); 00144 break; 00145 00146 case 0x02: //INTR 2 00147 kernel_panic(0, new_cpu_status); 00148 break; 00149 00150 case 0x03: //INTR 3 00151 kernel_panic(0, new_cpu_status); 00152 break; 00153 00154 case 0x04: //INTR 4 00155 kernel_panic(0, new_cpu_status); 00156 break; 00157 00158 case 0x05: //INTR 5 00159 kernel_panic(0, new_cpu_status); 00160 break; 00161 00162 case 0x06: //INTR 6 00163 kernel_panic(0, new_cpu_status); 00164 break; 00165 00166 case 0x07: //INTR 7 00167 kernel_panic(0, new_cpu_status); 00168 break; 00169 00170 case 0x08: //INTR 8 00171 kernel_panic(0, new_cpu_status); 00172 break; 00173 00174 case 0x09: //INTR 9 00175 kernel_panic(0, new_cpu_status); 00176 break; 00177 00178 case 0x0A: //INTR 10 00179 kernel_panic(0, new_cpu_status); 00180 break; 00181 00182 case 0x0B: //INTR 11 00183 kernel_panic(0, new_cpu_status); 00184 break; 00185 00186 case 0x0C: //INTR 12 00187 kernel_panic(0, new_cpu_status); 00188 break; 00189 00190 case 0x0D: //Exception 13 00191 kernel_panic(0, new_cpu_status); 00192 break; 00193 00194 case 0x0E: //INTR 14 00195 kernel_panic(0, new_cpu_status); 00196 break; 00197 00198 case 0x10: //INTR 16 00199 kernel_panic(0, new_cpu_status); 00200 break; 00201 00202 case 0x11: //INTR 17 00203 kernel_panic(0, new_cpu_status); 00204 break; 00205 00206 case 0x12: //INTR 18 00207 kernel_panic(0, new_cpu_status); 00208 break; 00209 00210 case 0x13: //INTR 19 00211 kernel_panic(0, new_cpu_status); 00212 break; 00213 00214 case 0x20: //INTR 32 //IRQ 0 00215 tick_counter += 10; 00216 if(booted == 1) { time(); 00217 new_cpu_status = schedule(new_cpu_status); //----------Der Scheduler wird aufgerufen, um dem Task zu wechseln---------- 00218 set_tss_stack(current_task->kernel_stack); }//----------Der neue Kernel-Stack des neuen Tasks wird in die TSS geladen---------- 00219 break; 00220 00221 case 0x21: //INTR 33 //IRQ 1 00222 get_key(); 00223 break; 00224 00225 case 0x26: 00226 irq6_fdc = 1; 00227 break; 00228 00229 case 0x30: //INTR 48 //SYSCALL 00230 new_cpu_status = syscall(new_cpu_status); //----------Der CPU-Zustand wird möglicherweise bei einem Syscall verändert---------- 00231 break; 00232 00233 default: //ALLES ANDERE 00234 kernel_panic(0, new_cpu_status); 00235 break; 00236 00237 } 00238 00239 if(registers->interrupt > 30 && registers->interrupt < 48) pic_send_eoi(registers->interrupt - 32); //----------Bei einem IRQ muss das EOI gesendet werden---------- 00240 return new_cpu_status; 00241 }