00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "src/common/shared.hpp"
00018 #include "src/arch/x86/gdt.hpp"
00019 #include "src/memory/heap.hpp"
00020 #include "src/memory/align.hpp"
00021
00022
00023
00024 #include "src/arch/x86/interr.hpp"
00025 #include "src/arch/x86/except_c.hpp"
00026
00027 inline void *kmalloc(size_t size, size_t alignment, uint32 facility, int (*destruct)(class Memory::Heap::heapbox*,void*))
00028 {
00029 return Memory::Heap::heap0.malloc(size,alignment,facility,destruct);
00030 }
00031
00032
00033 namespace Arch {
00034 namespace x86 {
00035 namespace Interr {
00036
00037
00038
00039 class idt_service kernel_idt;
00040
00041 void init_pic();
00042
00043
00044 void init()
00045 {
00046 idt_service *ptr = &kernel_idt;
00047
00048 GDT::kernel_tss_df.eip = (uint32) &double_fault;
00049 GDT::kernel_tss_sf.eip = (uint32) &stack_fault;
00050
00051 ptr->idt = (struct_idt*) kmalloc(sizeof(struct_idt) * DEF_INTERRUPT_COUNT, PAGE_ALIGN, FAC_INTERR|FAC_IDT, NULL);
00052 ptr->idtr = (struct_idtr*) kmalloc(sizeof(struct_idtr),0,FAC_INTERR|FAC_IDT, NULL);
00053 ptr->idtr -> s_limit = DEF_INTERRUPT_COUNT*sizeof(struct_idt) - 1;
00054 ptr->idtr -> s_base = ptr->idt;
00055 init_int_chains(ptr);
00056
00057
00058 ptr->lidt();
00059
00060
00061 init_pic();
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 void idt_service::set_int(char intno,void (offset)(),short select,short flags)
00083 {
00084 union
00085 {
00086 unsigned long ll;
00087 short ss[2];
00088 } uu;
00089
00090 uu.ll = intno;
00091 if (uu.ll >= DEF_INTERRUPT_COUNT) return ;
00092
00093 idt[intno].s_selector = select;
00094 idt[intno].s_flags = flags;
00095
00096 uu.ll = (uint32) offset;
00097 idt[intno].s_offset0_15 = uu.ss[0];
00098 idt[intno].s_offset16_31 = uu.ss[1];
00099 }
00100
00101
00102 void idt_service::install_except(void (_exc)())
00103 {
00104 exc = _exc;
00105 }
00106
00107
00108 void idt_service::lidt()
00109 {
00110
00111 __asm__ __volatile__ ("lidt (%%ebx)" : : "b" (idtr) );
00112 }
00113
00114
00115 void idt_service::cli()
00116 {
00117 __asm__ __volatile__ ("cli");
00118 }
00119
00120
00121 void idt_service::sti()
00122 {
00123 __asm__ __volatile__ ("sti");
00124 }
00125
00126
00127 };
00128 };
00129 };
00130
00131
00132
00133
00134
00135
00136