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 <<
064 <<
065 sos_ui16_t padding; <<
066 <<
067 <<
068 sos_ui16_t limit; 063 sos_ui16_t limit;
069 !! 064
070 !! 065
071 !! 066
072 !! 067
073 !! 068
074 !! 069
075 !! 070
076 !! 071
077 !! 072
078 !! 073 sos_ui32_t base_addr;
079 !! 074 } __attribute__((packed, aligned(8)));
080 sos_ui32_t base_addr; <<
081 } __attribute__((packed, aligned(4))); <<
082 075
083 076
084 077
085 078
086 079
087 080
088 081
089 #define BUILD_GDTE(descr_privilege_level,is_co 082 #define BUILD_GDTE(descr_privilege_level,is_code) \
090 ((struct x86_segment_descriptor) { 083 ((struct x86_segment_descriptor) { \
091 .limit_15_0= 0xffff, 084 .limit_15_0= 0xffff, \
092 .base_paged_addr_15_0= 0, 085 .base_paged_addr_15_0= 0, \
093 .base_paged_addr_23_16= 0, 086 .base_paged_addr_23_16= 0, \
094 .segment_type= ((is_code)?0xb:0 087 .segment_type= ((is_code)?0xb:0x3), \
095 088
096 089
097 090
098 091
099 092
100 093
101 094
102 095
103 096
104 097
105 098
106 099
107 100
108 101 \
109 .descriptor_type= 1, 102 .descriptor_type= 1, \
110 .dpl= ((descr_privileg 103 .dpl= ((descr_privilege_level) & 0x3), \
111 .present= 1, 104 .present= 1, \
112 .limit_19_16= 0xf, 105 .limit_19_16= 0xf, \
113 .custom= 0, 106 .custom= 0, \
114 .zero= 0, <<
115 .op_size= 1, 107 .op_size= 1, \
116 .granularity= 1, !! 108 .granularity= 1 \
117 .base_paged_addr_31_24= 0 <<
118 }) 109 })
119 110
120 111
121 112
122 static struct x86_segment_descriptor gdt[] = { 113 static struct x86_segment_descriptor gdt[] = {
123 [SOS_SEG_NULL] = (struct x86_segment_descri 114 [SOS_SEG_NULL] = (struct x86_segment_descriptor){ 0, },
124 [SOS_SEG_KCODE] = BUILD_GDTE(0, 1), 115 [SOS_SEG_KCODE] = BUILD_GDTE(0, 1),
125 [SOS_SEG_KDATA] = BUILD_GDTE(0, 0), 116 [SOS_SEG_KDATA] = BUILD_GDTE(0, 0),
126 [SOS_SEG_UCODE] = BUILD_GDTE(3, 1), 117 [SOS_SEG_UCODE] = BUILD_GDTE(3, 1),
127 [SOS_SEG_UDATA] = BUILD_GDTE(3, 0), 118 [SOS_SEG_UDATA] = BUILD_GDTE(3, 0),
128 [SOS_SEG_KERNEL_TSS] = { 0, } 119 [SOS_SEG_KERNEL_TSS] = { 0, }
129 120
130 }; 121 };
131 122
132 <<
133 sos_ret_t sos_gdt_subsystem_setup(void) 123 sos_ret_t sos_gdt_subsystem_setup(void)
134 { 124 {
135 struct x86_gdt_register gdtr; 125 struct x86_gdt_register gdtr;
136 126
137 <<
138 gdtr.padding = ~0; <<
139 <<
140 127
141 gdtr.base_addr = (sos_ui32_t) gdt; 128 gdtr.base_addr = (sos_ui32_t) gdt;
142 129
143 130
144 131
145 gdtr.limit = sizeof(gdt) - 1; 132 gdtr.limit = sizeof(gdt) - 1;
146 133
147 134
148 135
149 136
150 137
151 asm volatile ("lgdt %0 \n\ 138 asm volatile ("lgdt %0 \n\
152 ljmp %1,$1f \n\ 139 ljmp %1,$1f \n\
153 1: \n\ 140 1: \n\
154 movw %2, %%ax \n\ 141 movw %2, %%ax \n\
155 movw %%ax, %%ss \n\ 142 movw %%ax, %%ss \n\
156 movw %%ax, %%ds \n\ 143 movw %%ax, %%ds \n\
157 movw %%ax, %%es \n\ 144 movw %%ax, %%es \n\
158 movw %%ax, %%fs \n\ 145 movw %%ax, %%fs \n\
159 movw %%ax, %%gs" 146 movw %%ax, %%gs"
160 : 147 :
161 :"m"(gdtr.limit) !! 148 :"m"(gdtr),
162 <<
163 <<
164 , <<
165 "i"(SOS_BUILD_SEGMENT_REG_VAL 149 "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE)),
166 "i"(SOS_BUILD_SEGMENT_REG_VAL 150 "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA))
167 :"memory","eax"); 151 :"memory","eax");
168 152
169 return SOS_OK; 153 return SOS_OK;
170 } 154 }
171 155
172 156
173 sos_ret_t sos_gdt_register_kernel_tss(sos_vadd 157 sos_ret_t sos_gdt_register_kernel_tss(sos_vaddr_t tss_vaddr)
174 { 158 {
175 sos_ui16_t regval_tss; 159 sos_ui16_t regval_tss;
176 160
177 161
178 gdt[SOS_SEG_KERNEL_TSS] 162 gdt[SOS_SEG_KERNEL_TSS]
179 = (struct x86_segment_descriptor) { 163 = (struct x86_segment_descriptor) {
180 .limit_15_0= 0x67, 164 .limit_15_0= 0x67,
181 .base_paged_addr_15_0= (tss_vaddr) & 0x 165 .base_paged_addr_15_0= (tss_vaddr) & 0xffff,
182 .base_paged_addr_23_16= (tss_vaddr >> 16 166 .base_paged_addr_23_16= (tss_vaddr >> 16) & 0xff,
183 .segment_type= 0x9, 167 .segment_type= 0x9,
184 .descriptor_type= 0, 168 .descriptor_type= 0,
185 .dpl= 3, 169 .dpl= 3,
186 .present= 1, 170 .present= 1,
187 .limit_19_16= 0, 171 .limit_19_16= 0,
188 .custom= 0, 172 .custom= 0,
189 .zero= 0, <<
190 .op_size= 0, 173 .op_size= 0,
191 .granularity= 1, 174 .granularity= 1,
192 .base_paged_addr_31_24= (tss_vaddr >> 24 175 .base_paged_addr_31_24= (tss_vaddr >> 24) & 0xff
193 }; 176 };
194 177
195 178
196 regval_tss = SOS_BUILD_SEGMENT_REG_VALUE(0, 179 regval_tss = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE,
197 SOS 180 SOS_SEG_KERNEL_TSS);
198 asm ("ltr %0" : :"r"(regval_tss)); 181 asm ("ltr %0" : :"r"(regval_tss));
199 182
200 return SOS_OK; 183 return SOS_OK;
201 } 184 }
202 185
203 186