POK(kernelpart)
|
00001 /* 00002 * POK header 00003 * 00004 * The following file is a part of the POK project. Any modification should 00005 * made according to the POK licence. You CANNOT use this file or a part of 00006 * this file is this part of a file for your own project 00007 * 00008 * For more information on the POK licence, please see our LICENCE FILE 00009 * 00010 * Please follow the coding guidelines described in doc/CODING_GUIDELINES 00011 * 00012 * Copyright (c) 2007-2009 POK team 00013 * 00014 * Created by julien on Thu Jan 15 23:34:13 2009 00015 */ 00016 00017 00018 #include <libc.h> 00019 00020 #include <types.h> 00021 #include <errno.h> 00022 00023 #include "gdt.h" 00024 #include "sysdesc.h" 00025 #include "tss.h" 00026 00027 #ifndef POK_NEEDS_THREADS 00028 #define POK_CONFIG_NB_THREADS 0 00029 #endif 00030 00031 #ifndef POK_NEEDS_PARTITIONS 00032 #define POK_CONFIG_NB_PARTITIONS 0 00033 #endif 00034 00035 #define GDT_SIZE 256 00036 00037 gdt_entry_t pok_gdt[GDT_SIZE]; 00038 00039 tss_t pok_tss; 00040 00041 pok_ret_t pok_gdt_init() 00042 { 00043 sysdesc_t sysdesc; 00044 00045 /* Set null descriptor and clear table */ 00046 memset(pok_gdt, 0, sizeof (gdt_entry_t) * GDT_SIZE); 00047 00048 /* Set kernel descriptors */ 00049 gdt_set_segment(GDT_CORE_CODE_SEGMENT, 0, ~0UL, GDTE_CODE, 0); 00050 gdt_set_segment(GDT_CORE_DATA_SEGMENT, 0, ~0UL, GDTE_DATA, 0); 00051 00052 /* Load GDT */ 00053 sysdesc.limit = sizeof (pok_gdt); 00054 sysdesc.base = (uint32_t)pok_gdt; 00055 00056 asm ("lgdt %0" 00057 : 00058 : "m" (sysdesc)); 00059 00060 /* Reload Segments */ 00061 asm ("ljmp %0, $1f \n" 00062 "1: \n" 00063 "mov %1, %%ax \n" 00064 "mov %%ax, %%ds \n" 00065 "mov %%ax, %%es \n" 00066 "mov %%ax, %%fs \n" 00067 "mov %%ax, %%gs \n" 00068 "mov %%ax, %%ss \n" 00069 : 00070 : "i" (GDT_CORE_CODE_SEGMENT << 3), 00071 "i" (GDT_CORE_DATA_SEGMENT << 3) 00072 : "eax"); 00073 00074 pok_tss_init(); 00075 00076 return (POK_ERRNO_OK); 00077 } 00078 00079 int pok_tss_init() 00080 { 00081 uint16_t sel = GDT_BUILD_SELECTOR(GDT_TSS_SEGMENT, 0, 0); 00082 00083 memset(&pok_tss, 0, sizeof (tss_t)); 00084 00085 pok_tss.ss0 = GDT_BUILD_SELECTOR(GDT_CORE_DATA_SEGMENT, 0, 0); 00086 00087 gdt_set_system(GDT_TSS_SEGMENT, (uint32_t)&pok_tss, 00088 sizeof (tss_t), GDTE_TSS, 0); 00089 00090 asm ("ltr %0" : :"m"(sel)); 00091 return (POK_ERRNO_OK); 00092 } 00093 00094 void tss_set_esp0(uint32_t esp0) 00095 { 00096 pok_tss.esp0 = esp0; 00097 } 00098 00099 void gdt_set_segment(uint16_t index, 00100 uint32_t base_address, 00101 uint32_t limit, 00102 e_gdte_type t, 00103 int dpl) 00104 { 00105 if (limit > (1 << 20)) /* 4K granularity */ 00106 { 00107 pok_gdt[index].limit_low = (limit >> 12) & 0xFFFF; 00108 pok_gdt[index].limit_high = (limit >> 28) & 0xF; 00109 pok_gdt[index].granularity = 1; 00110 } 00111 else /* 1B granularity */ 00112 { 00113 pok_gdt[index].limit_low = limit & 0xFFFF; 00114 pok_gdt[index].limit_high = (limit >> 16) & 0xFF; 00115 pok_gdt[index].granularity = 0; 00116 } 00117 00118 pok_gdt[index].base_low = base_address & 0xFFFFFF; 00119 pok_gdt[index].base_high = (base_address >> 24) & 0xFF; 00120 00121 pok_gdt[index].type = t & 0xF; 00122 pok_gdt[index].dpl = dpl & 0x3; 00123 00124 pok_gdt[index].s = 1; /* Segment is data/code type */ 00125 pok_gdt[index].present = 1; 00126 pok_gdt[index].available = 0; 00127 pok_gdt[index].op_size = 1; /* We work on 32 bits segments */ 00128 } 00129 00130 void gdt_set_system(uint16_t index, 00131 uint32_t base_address, 00132 uint32_t limit, 00133 e_gdte_type t, 00134 int dpl) 00135 { 00136 pok_gdt[index].limit_low = limit & 0xFFFF; 00137 pok_gdt[index].limit_high = (limit >> 16) & 0xFF; 00138 pok_gdt[index].base_low = base_address & 0xFFFFFF; 00139 pok_gdt[index].base_high = (base_address >> 24) & 0xFF; 00140 00141 pok_gdt[index].type = t & 0xF; 00142 pok_gdt[index].dpl = dpl & 0x3; 00143 00144 pok_gdt[index].s = 0; /* Segment is system type */ 00145 pok_gdt[index].present = 1; 00146 pok_gdt[index].available = 0; 00147 pok_gdt[index].op_size = 0; 00148 } 00149 00150 void gdt_enable(uint16_t index) 00151 { 00152 pok_gdt[index].present = 1; 00153 } 00154 00155 void gdt_disable(uint16_t index) 00156 { 00157 pok_gdt[index].present = 0; 00158 } 00159 00160 /* 00161 * DEPRECATED 00162 * 00163 uint32_t gdt_segment_base(uint16_t idx) 00164 { 00165 uint32_t base; 00166 00167 base = pok_gdt[idx].base_low | (pok_gdt[idx].base_high << 24); 00168 00169 return base; 00170 } 00171 */ 00172