00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <asm/types.h>
00015 #include <asm/tss.h>
00016 #include <asm/desc.h>
00017
00018 #define CODE_RE_DESC_TYPE 0x1A
00019 #define DATA_RW_DESC_TYPE 0x12
00020 #define INTERRUPT_GATE_TYPE 0x0E
00021 #define TRAP_GATE_TYPE 0x0F
00022 #define TASK_GATE_TYPE 0x05
00023 #define TSS_DESC_TYPE 0x09
00024 #define GATE_PRESENT_FLAG 1 << 7
00025 #define GRANULARITY_FLAG 1 << 7
00026 #define DB_FLAG 1 << 6
00027
00028 #define set_type_byte(type) \
00029 u8 type_byte = 0; \
00030 type_byte |= GATE_PRESENT_FLAG; \
00031 type_byte |= type; \
00032 type_byte |= dpl << 5;
00033
00034 extern struct desc_struct idt_table[256];
00035
00036 void set_IDT_gate_descriptor(struct desc_struct *desc_table, u16 selector, void *offset, u8 type_byte)
00037 {
00038 u16 *table = (u16 *)desc_table;
00039 u32 offset_32 = (u32)offset;
00040
00041 table[0] = (u16)(offset_32 & 0xFFFF);
00042 table[1] = selector;
00043 table[2] = (type_byte << 8);
00044 table[3] = (u16)((offset_32 >> 16) & 0xFFFF);
00045 }
00046
00047 void set_TSS_descriptor(struct desc_struct *desc_table, void *offset, u32 limit, u8 type_byte)
00048 {
00049 u16 *table = (u16 *)desc_table;
00050 u32 base_32 = (u32)offset;
00051
00052 table[0] = (u16)(limit & 0xFFFF);
00053 table[1] = (u16)(base_32 & 0xFFFF);
00054 table[2] = (u16)((type_byte << 8) | ((base_32 >> 16) & 0xFF));
00055 table[3] = (u16)(((base_32 >> 16) & 0xFF00) | ((limit >> 16) & 0x0F));
00056 }
00057
00058 void set_GDT_descriptor(struct desc_struct *desc_table, u32 base, u32 limit, u8 type_byte, u8 db)
00059 {
00060 u16 *table = (u16 *)desc_table;
00061
00062 table[0] = (u16)(limit & 0xFFFF);
00063 table[1] = (u16)(base & 0xFFFF);
00064 table[2] = (u16)((type_byte << 8) | ((base >> 16) & 0xFF));
00065 table[3] = (u16)(((base >> 16) & 0xFF00) | ((limit >> 16) & 0x0F) | ((db & 0x01) << 6));
00066 }
00067
00068 void set_code_desc(u32 entry, u32 base, u32 limit, u8 dpl, u8 db)
00069 {
00070 set_type_byte(CODE_RE_DESC_TYPE);
00071 set_GDT_descriptor(gdt_table + entry, base, limit, type_byte, db);
00072 }
00073
00074 void set_data_desc(u32 entry, u32 base, u32 limit, u8 dpl, u8 db)
00075 {
00076 set_type_byte(DATA_RW_DESC_TYPE);
00077 set_GDT_descriptor(gdt_table + entry, base, limit, type_byte, db);
00078 }
00079
00080 void set_interrupt_gate(u32 entry, u16 selector, void *offset, u8 dpl)
00081 {
00082 set_type_byte(INTERRUPT_GATE_TYPE);
00083 set_IDT_gate_descriptor(idt_table + entry, selector, offset, type_byte);
00084 }
00085
00086 void set_trap_gate(u32 entry, u16 selector, void *offset, u8 dpl)
00087 {
00088 set_type_byte(TRAP_GATE_TYPE);
00089 set_IDT_gate_descriptor(idt_table + entry, selector, offset, type_byte);
00090 }
00091
00092 void set_task_gate(u32 entry, u16 selector, u8 dpl)
00093 {
00094 set_type_byte(TASK_GATE_TYPE);
00095 set_IDT_gate_descriptor(idt_table + entry, selector, 0, type_byte);
00096 }
00097
00098 void set_TSS_desc(u32 entry, void *offset, u32 limit, u8 dpl)
00099 {
00100 set_type_byte(TSS_DESC_TYPE);
00101 set_TSS_descriptor(gdt_table + entry, offset, limit, type_byte);
00102 }