Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 #include "segment.h" 019 #include "segment.h"
020 020
021 #include "gdt.h" 021 #include "gdt.h"
022 022
023 023
024 024
025 025
026 026
027 027
028 028
029 029
030 struct x86_segment_descriptor 030 struct x86_segment_descriptor
031 { 031 {
032 032
033 sos_ui16_t limit_15_0; 033 sos_ui16_t limit_15_0;
034 sos_ui16_t base_paged_addr_15_0; 034 sos_ui16_t base_paged_addr_15_0;
035 035
036 036
037 sos_ui8_t base_paged_addr_23_16; 037 sos_ui8_t base_paged_addr_23_16;
038 sos_ui8_t segment_type:4; 038 sos_ui8_t segment_type:4;
039 039
040 sos_ui8_t descriptor_type:1; 040 sos_ui8_t descriptor_type:1;
041 sos_ui8_t dpl:2; 041 sos_ui8_t dpl:2;
042 sos_ui8_t present:1; 042 sos_ui8_t present:1;
043 043
044 sos_ui8_t limit_19_16:4; 044 sos_ui8_t limit_19_16:4;
045 sos_ui8_t custom:1; 045 sos_ui8_t custom:1;
046 sos_ui8_t zero:1; 046 sos_ui8_t zero:1;
047 sos_ui8_t op_size:1; 047 sos_ui8_t op_size:1;
048 sos_ui8_t granularity:1; 048 sos_ui8_t granularity:1;
049 049
050 sos_ui8_t base_paged_addr_31_24; 050 sos_ui8_t base_paged_addr_31_24;
051 } __attribute__ ((packed, aligned (8))); 051 } __attribute__ ((packed, aligned (8)));
052 052
053 053
054 054
055 055
056 056
057 057
058 058
059 059
060 060
061 struct x86_gdt_register { 061 struct x86_gdt_register {
062 062
063 sos_ui16_t limit; 063 sos_ui16_t limit;
064 064
065 065
066 066
067 067
068 068
069 069
070 070
071 071
072 072
073 sos_ui32_t base_addr; 073 sos_ui32_t base_addr;
074 } __attribute__((packed, aligned(8))); 074 } __attribute__((packed, aligned(8)));
075 075
076 076
077 077
078 078
079 079
080 080
081 081
082 #define BUILD_GDTE(descr_privilege_level,is_co 082 #define BUILD_GDTE(descr_privilege_level,is_code) \
083 ((struct x86_segment_descriptor) { 083 ((struct x86_segment_descriptor) { \
084 .limit_15_0= 0xffff, 084 .limit_15_0= 0xffff, \
085 .base_paged_addr_15_0= 0, 085 .base_paged_addr_15_0= 0, \
086 .base_paged_addr_23_16= 0, 086 .base_paged_addr_23_16= 0, \
087 .segment_type= ((is_code)?0xb:0 087 .segment_type= ((is_code)?0xb:0x3), \
088 088
089 089
090 090
091 091
092 092
093 093
094 094
095 095
096 096
097 097
098 098
099 099
100 100
101 101 \
102 .descriptor_type= 1, 102 .descriptor_type= 1, \
103 .dpl= ((descr_privileg 103 .dpl= ((descr_privilege_level) & 0x3), \
104 .present= 1, 104 .present= 1, \
105 .limit_19_16= 0xf, 105 .limit_19_16= 0xf, \
106 .custom= 0, 106 .custom= 0, \
107 .op_size= 1, 107 .op_size= 1, \
108 .granularity= 1 108 .granularity= 1 \
109 }) 109 })
110 110
111 111
112 112
113 static struct x86_segment_descriptor gdt[] = { 113 static struct x86_segment_descriptor gdt[] = {
114 [SOS_SEG_NULL] = (struct x86_segment_descri 114 [SOS_SEG_NULL] = (struct x86_segment_descriptor){ 0, },
115 [SOS_SEG_KCODE] = BUILD_GDTE(0, 1), 115 [SOS_SEG_KCODE] = BUILD_GDTE(0, 1),
116 [SOS_SEG_KDATA] = BUILD_GDTE(0, 0), 116 [SOS_SEG_KDATA] = BUILD_GDTE(0, 0),
117 [SOS_SEG_UCODE] = BUILD_GDTE(3, 1), 117 [SOS_SEG_UCODE] = BUILD_GDTE(3, 1),
118 [SOS_SEG_UDATA] = BUILD_GDTE(3, 0), 118 [SOS_SEG_UDATA] = BUILD_GDTE(3, 0),
119 [SOS_SEG_KERNEL_TSS] = { 0, } 119 [SOS_SEG_KERNEL_TSS] = { 0, }
120 120
121 }; 121 };
122 122
123 sos_ret_t sos_gdt_subsystem_setup(void) 123 sos_ret_t sos_gdt_subsystem_setup(void)
124 { 124 {
125 struct x86_gdt_register gdtr; 125 struct x86_gdt_register gdtr;
126 126
127 127
128 gdtr.base_addr = (sos_ui32_t) gdt; 128 gdtr.base_addr = (sos_ui32_t) gdt;
129 129
130 130
131 131
132 gdtr.limit = sizeof(gdt) - 1; 132 gdtr.limit = sizeof(gdt) - 1;
133 133
134 134
135 135
136 136
137 137
138 asm volatile ("lgdt %0 \n\ 138 asm volatile ("lgdt %0 \n\
139 ljmp %1,$1f \n\ 139 ljmp %1,$1f \n\
140 1: \n\ 140 1: \n\
141 movw %2, %%ax \n\ 141 movw %2, %%ax \n\
142 movw %%ax, %%ss \n\ 142 movw %%ax, %%ss \n\
143 movw %%ax, %%ds \n\ 143 movw %%ax, %%ds \n\
144 movw %%ax, %%es \n\ 144 movw %%ax, %%es \n\
145 movw %%ax, %%fs \n\ 145 movw %%ax, %%fs \n\
146 movw %%ax, %%gs" 146 movw %%ax, %%gs"
147 : 147 :
148 :"m"(gdtr), 148 :"m"(gdtr),
149 "i"(SOS_BUILD_SEGMENT_REG_VAL 149 "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE)),
150 "i"(SOS_BUILD_SEGMENT_REG_VAL 150 "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA))
151 :"memory","eax"); 151 :"memory","eax");
152 152
153 return SOS_OK; 153 return SOS_OK;
154 } 154 }
155 155
156 156
157 sos_ret_t sos_gdt_register_kernel_tss(sos_vadd 157 sos_ret_t sos_gdt_register_kernel_tss(sos_vaddr_t tss_vaddr)
158 { 158 {
159 sos_ui16_t regval_tss; 159 sos_ui16_t regval_tss;
160 160
161 161
162 gdt[SOS_SEG_KERNEL_TSS] 162 gdt[SOS_SEG_KERNEL_TSS]
163 = (struct x86_segment_descriptor) { 163 = (struct x86_segment_descriptor) {
164 .limit_15_0= 0x67, 164 .limit_15_0= 0x67,
165 .base_paged_addr_15_0= (tss_vaddr) & 0x 165 .base_paged_addr_15_0= (tss_vaddr) & 0xffff,
166 .base_paged_addr_23_16= (tss_vaddr >> 16 166 .base_paged_addr_23_16= (tss_vaddr >> 16) & 0xff,
167 .segment_type= 0x9, 167 .segment_type= 0x9,
168 .descriptor_type= 0, 168 .descriptor_type= 0,
169 .dpl= 3, 169 .dpl= 3,
170 .present= 1, 170 .present= 1,
171 .limit_19_16= 0, 171 .limit_19_16= 0,
172 .custom= 0, 172 .custom= 0,
173 .op_size= 0, 173 .op_size= 0,
174 .granularity= 1, 174 .granularity= 1,
175 .base_paged_addr_31_24= (tss_vaddr >> 24 175 .base_paged_addr_31_24= (tss_vaddr >> 24) & 0xff
176 }; 176 };
177 177
178 178
179 regval_tss = SOS_BUILD_SEGMENT_REG_VALUE(0, 179 regval_tss = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE,
180 SOS 180 SOS_SEG_KERNEL_TSS);
181 asm ("ltr %0" : :"r"(regval_tss)); 181 asm ("ltr %0" : :"r"(regval_tss));
182 182
183 return SOS_OK; 183 return SOS_OK;
184 } 184 }
185 185
186 186