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 019
020 020
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <sos/klibc.h> 022 #include <sos/klibc.h>
023 #include <drivers/bochs.h> 023 #include <drivers/bochs.h>
024 #include <drivers/x86_videomem.h> 024 #include <drivers/x86_videomem.h>
025 #include <hwcore/segment.h> 025 #include <hwcore/segment.h>
026 026
027 #include "cpu_context.h" 027 #include "cpu_context.h"
028 028
029 029
030 030
031 031
032 032
033 033
034 034
035 035
036 036
037 037
038 038
039 039
040 040
041 041
042 042
043 struct sos_cpu_state { !! 043 struct sos_cpu_kstate {
044 044
045 045
046 046
047 sos_ui16_t gs; 047 sos_ui16_t gs;
048 sos_ui16_t fs; 048 sos_ui16_t fs;
049 sos_ui16_t es; 049 sos_ui16_t es;
050 sos_ui16_t ds; 050 sos_ui16_t ds;
051 sos_ui16_t cpl0_ss; !! 051 sos_ui16_t ss;
052 <<
053 <<
054 sos_ui16_t alignment_padding; 052 sos_ui16_t alignment_padding;
055 sos_ui32_t eax; 053 sos_ui32_t eax;
056 sos_ui32_t ebx; 054 sos_ui32_t ebx;
057 sos_ui32_t ecx; 055 sos_ui32_t ecx;
058 sos_ui32_t edx; 056 sos_ui32_t edx;
059 sos_ui32_t esi; 057 sos_ui32_t esi;
060 sos_ui32_t edi; 058 sos_ui32_t edi;
061 sos_ui32_t ebp; 059 sos_ui32_t ebp;
062 060
063 061
064 sos_ui32_t error_code; 062 sos_ui32_t error_code;
065 sos_vaddr_t eip; 063 sos_vaddr_t eip;
066 sos_ui32_t cs; !! 064 sos_ui32_t cs;
067 <<
068 sos_ui32_t eflags; 065 sos_ui32_t eflags;
069 066
070 067
071 } __attribute__((packed)); 068 } __attribute__((packed));
072 069
073 070
074 <<
075 <<
076 <<
077 <<
078 <<
079 <<
080 <<
081 <<
082 <<
083 <<
084 <<
085 <<
086 <<
087 #define GET_CPU_CS_REGISTER_VALUE(pushed_ui32_ <<
088 ( (pushed_ui32_cs_value) & 0xffff ) <<
089 <<
090 <<
091 <<
092 <<
093 <<
094 struct sos_cpu_kstate <<
095 { <<
096 struct sos_cpu_state regs; <<
097 } __attribute__((packed)); <<
098 <<
099 <<
100 <<
101 <<
102 <<
103 <<
104 <<
105 static void core_routine (sos_cpu_kstate_funct 071 static void core_routine (sos_cpu_kstate_function_arg1_t *start_func,
106 sos_ui32_t start_arg 072 sos_ui32_t start_arg,
107 sos_cpu_kstate_funct 073 sos_cpu_kstate_function_arg1_t *exit_func,
108 sos_ui32_t exit_arg) 074 sos_ui32_t exit_arg)
109 __attribute__((noreturn)); 075 __attribute__((noreturn));
110 076
111 static void core_routine (sos_cpu_kstate_funct 077 static void core_routine (sos_cpu_kstate_function_arg1_t *start_func,
112 sos_ui32_t start_arg 078 sos_ui32_t start_arg,
113 sos_cpu_kstate_funct 079 sos_cpu_kstate_function_arg1_t *exit_func,
114 sos_ui32_t exit_arg) 080 sos_ui32_t exit_arg)
115 { 081 {
116 start_func(start_arg); 082 start_func(start_arg);
117 exit_func(exit_arg); 083 exit_func(exit_arg);
118 084
119 SOS_ASSERT_FATAL(! "The exit function of the 085 SOS_ASSERT_FATAL(! "The exit function of the thread should NOT return !");
120 for(;;); 086 for(;;);
121 } 087 }
122 088
123 089
124 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_s !! 090 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_kstate **ctxt,
125 sos_cpu_kstate_f 091 sos_cpu_kstate_function_arg1_t *start_func,
126 sos_ui32_t star 092 sos_ui32_t start_arg,
127 sos_vaddr_t stac 093 sos_vaddr_t stack_bottom,
128 sos_size_t stac 094 sos_size_t stack_size,
129 sos_cpu_kstate_f 095 sos_cpu_kstate_function_arg1_t *exit_func,
130 sos_ui32_t exit 096 sos_ui32_t exit_arg)
131 { 097 {
132 <<
133 struct sos_cpu_kstate *kctxt; <<
134 <<
135 098
136 099
137 100
138 101
139 102
140 103
141 104
142 105
143 106
144 107
145 108
146 109
147 110
148 111
149 112
150 113
151 114
152 115
153 116
154 117
155 118
156 119
157 sos_vaddr_t tmp_vaddr = stack_bottom + stack 120 sos_vaddr_t tmp_vaddr = stack_bottom + stack_size;
158 sos_ui32_t *stack = (sos_ui32_t*)tmp_vaddr; 121 sos_ui32_t *stack = (sos_ui32_t*)tmp_vaddr;
159 122
160 123
161 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS !! 124 #ifdef SOS_CPU_KSTATE_DETECT_UNINIT_VARS
162 memset((void*)stack_bottom, SOS_CPU_STATE_ST !! 125 memset((void*)stack_bottom, SOS_CPU_KSTATE_STACK_POISON, stack_size);
163 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STAC !! 126 #elif defined(SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW)
164 sos_cpu_state_prepare_detect_kernel_stack_ov !! 127 sos_cpu_kstate_prepare_detect_stack_overflow(stack_bottom, stack_size);
165 #endif 128 #endif
166 129
167 130
168 131
169 *(--stack) = exit_arg; 132 *(--stack) = exit_arg;
170 *(--stack) = (sos_ui32_t)exit_func; 133 *(--stack) = (sos_ui32_t)exit_func;
171 *(--stack) = start_arg; 134 *(--stack) = start_arg;
172 *(--stack) = (sos_ui32_t)start_func; 135 *(--stack) = (sos_ui32_t)start_func;
173 *(--stack) = 0; 136 *(--stack) = 0;
174 137
175 138
176 139
177 140
178 141
179 142
180 143
181 144
182 145
183 tmp_vaddr = ((sos_vaddr_t)stack) - sizeof(s 146 tmp_vaddr = ((sos_vaddr_t)stack) - sizeof(struct sos_cpu_kstate);
184 kctxt = (struct sos_cpu_kstate*)tmp_vaddr; !! 147 *ctxt = (struct sos_cpu_kstate*)tmp_vaddr;
185 148
186 149
187 memset(kctxt, 0x0, sizeof(struct sos_cpu_kst !! 150 memset(*ctxt, 0x0, sizeof(struct sos_cpu_kstate));
188 151
189 152
190 153
191 kctxt->regs.eip = (sos_ui32_t)core_routine; !! 154 (*ctxt)->eip = (sos_ui32_t)core_routine;
192 155
193 156
194 kctxt->regs.cs !! 157 (*ctxt)->cs = SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KCODE);
195 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO !! 158 (*ctxt)->ds = SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA);
196 kctxt->regs.ds !! 159 (*ctxt)->es = SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA);
197 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO !! 160 (*ctxt)->ss = SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA);
198 kctxt->regs.es <<
199 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
200 kctxt->regs.cpl0_ss <<
201 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
202 161
203 162
204 163
205 kctxt->regs.eflags = (1 << 9); !! 164 (*ctxt)->eflags = (1 << 9);
206 <<
207 <<
208 *ctxt = (struct sos_cpu_state*) kctxt; <<
209 165
210 return SOS_OK; 166 return SOS_OK;
211 } 167 }
212 168
213 169
214 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_ !! 170 #if defined(SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW)
215 void 171 void
216 sos_cpu_state_prepare_detect_kernel_stack_over !! 172 sos_cpu_kstate_prepare_detect_stack_overflow(const struct sos_cpu_kstate *ctxt,
217 !! 173 sos_vaddr_t stack_bottom,
218 !! 174 sos_size_t stack_size)
219 { 175 {
220 sos_size_t poison_size = SOS_CPU_STATE_DETEC !! 176 sos_size_t poison_size = SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW;
221 if (poison_size > stack_size) 177 if (poison_size > stack_size)
222 poison_size = stack_size; 178 poison_size = stack_size;
223 179
224 memset((void*)stack_bottom, SOS_CPU_STATE_ST !! 180 memset((void*)stack_bottom, SOS_CPU_KSTATE_STACK_POISON, poison_size);
225 } 181 }
226 182
227 183
228 void 184 void
229 sos_cpu_state_detect_kernel_stack_overflow(con !! 185 sos_cpu_kstate_detect_stack_overflow(const struct sos_cpu_kstate *ctxt,
230 sos !! 186 sos_vaddr_t stack_bottom,
231 sos !! 187 sos_size_t stack_size)
232 { 188 {
233 unsigned char *c; 189 unsigned char *c;
234 int i; 190 int i;
235 191
236 <<
237 <<
238 <<
239 <<
240 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stac 192 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stack_bottom);
241 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeo 193 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeof(struct sos_cpu_kstate)
242 <= stack_bottom + stack_siz 194 <= stack_bottom + stack_size);
243 <<
244 <<
245 for (c = (unsigned char*) stack_bottom, i = 195 for (c = (unsigned char*) stack_bottom, i = 0 ;
246 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_ !! 196 (i < SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW) && (i < stack_size) ;
247 c++, i++) 197 c++, i++)
248 { 198 {
249 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POI !! 199 SOS_ASSERT_FATAL(SOS_CPU_KSTATE_STACK_POISON == *c);
250 } 200 }
251 } 201 }
252 #endif 202 #endif
253 203
254 204
255 !! 205 sos_vaddr_t sos_cpu_kstate_get_PC(const struct sos_cpu_kstate *ctxt)
256 <<
257 <<
258 <<
259 <<
260 sos_vaddr_t sos_cpu_context_get_PC(const struc <<
261 { 206 {
262 SOS_ASSERT_FATAL(NULL != ctxt); 207 SOS_ASSERT_FATAL(NULL != ctxt);
263 <<
264 <<
265 <<
266 return ctxt->eip; 208 return ctxt->eip;
267 } 209 }
268 210
269 211
270 sos_vaddr_t sos_cpu_context_get_SP(const struc !! 212 sos_vaddr_t sos_cpu_kstate_get_SP(const struct sos_cpu_kstate *ctxt)
271 { 213 {
272 SOS_ASSERT_FATAL(NULL != ctxt); 214 SOS_ASSERT_FATAL(NULL != ctxt);
273 <<
274 <<
275 <<
276 <<
277 return (sos_vaddr_t)ctxt; 215 return (sos_vaddr_t)ctxt;
278 } 216 }
279 217
280 218
281 void sos_cpu_context_dump(const struct sos_cpu !! 219 void sos_cpu_kstate_dump(const struct sos_cpu_kstate *ctxt)
282 { 220 {
283 char buf[128]; 221 char buf[128];
284 snprintf(buf, sizeof(buf), 222 snprintf(buf, sizeof(buf),
285 "CPU: eip=%x esp=%x eflags=%x cs=%x 223 "CPU: eip=%x esp=%x eflags=%x cs=%x ds=%x ss=%x err=%x",
286 (unsigned)ctxt->eip, (unsigned)ctxt 224 (unsigned)ctxt->eip, (unsigned)ctxt, (unsigned)ctxt->eflags,
287 (unsigned)GET_CPU_CS_REGISTER_VALUE !! 225 (unsigned)ctxt->cs, (unsigned)ctxt->ds, (unsigned)ctxt->ss,
288 (unsigned)ctxt->cpl0_ss, <<
289 (unsigned)ctxt->error_code); 226 (unsigned)ctxt->error_code);
290 sos_bochs_putstring(buf); sos_bochs_putstrin 227 sos_bochs_putstring(buf); sos_bochs_putstring("\n");
291 sos_x86_videomem_putstring(23, 0, 228 sos_x86_videomem_putstring(23, 0,
292 SOS_X86_VIDEO_FG_BLA 229 SOS_X86_VIDEO_FG_BLACK | SOS_X86_VIDEO_BG_LTGRAY,
293 buf); 230 buf);
294 } 231 }
295 232
296 233
297 !! 234 sos_ui32_t sos_cpu_kstate_get_EX_info(const struct sos_cpu_kstate *ctxt)
298 <<
299 <<
300 <<
301 <<
302 sos_ui32_t sos_cpu_context_get_EX_info(const s <<
303 { 235 {
304 SOS_ASSERT_FATAL(NULL != ctxt); 236 SOS_ASSERT_FATAL(NULL != ctxt);
305 return ctxt->error_code; 237 return ctxt->error_code;
306 } 238 }
307 239
308 240
309 sos_vaddr_t 241 sos_vaddr_t
310 sos_cpu_context_get_EX_faulting_vaddr(const st !! 242 sos_cpu_kstate_get_EX_faulting_vaddr(const struct sos_cpu_kstate *ctxt)
311 { 243 {
312 sos_ui32_t cr2; 244 sos_ui32_t cr2;
313 245
314 !! 246
315 !! 247
316 <<
317 <<
318 <<
319 <<
320 <<
321 <<
322 <<
323 <<
324 <<
325 <<
326 <<
327 asm volatile ("movl %%cr2, %0" 248 asm volatile ("movl %%cr2, %0"
328 :"=r"(cr2) 249 :"=r"(cr2)
329 : ); 250 : );
330 251
331 return cr2; 252 return cr2;
332 } 253 }
333 254
334 255
335 !! 256 sos_ui32_t sos_backtrace(const struct sos_cpu_kstate *cpu_kstate,
336 <<
337 <<
338 <<
339 <<
340 sos_ui32_t sos_backtrace(const struct sos_cpu_ <<
341 sos_ui32_t max_depth, 257 sos_ui32_t max_depth,
342 sos_vaddr_t stack_bot 258 sos_vaddr_t stack_bottom,
343 sos_size_t stack_size 259 sos_size_t stack_size,
344 sos_backtrace_callbac 260 sos_backtrace_callback_t * backtracer,
345 void *custom_arg) 261 void *custom_arg)
346 { 262 {
347 int depth; 263 int depth;
348 sos_vaddr_t callee_PC, caller_frame; 264 sos_vaddr_t callee_PC, caller_frame;
349 265
350 266
351 267
352 268
353 269
354 270
355 271
356 272
357 273
358 274
359 275
360 276
361 277
362 278
363 279
364 280
365 281
366 282
367 283
368 284
369 285
370 286
371 287
372 288
373 289
374 290
375 291
376 292
377 293
378 294
379 if (cpu_state) !! 295 if (cpu_kstate)
380 { 296 {
381 callee_PC = cpu_state->eip; !! 297 callee_PC = cpu_kstate->eip;
382 caller_frame = cpu_state->ebp; !! 298 caller_frame = cpu_kstate->ebp;
383 } 299 }
384 else 300 else
385 { 301 {
386 302
387 callee_PC = (sos_vaddr_t)__builtin_re 303 callee_PC = (sos_vaddr_t)__builtin_return_address(0);
388 caller_frame = (sos_vaddr_t)__builtin_fr 304 caller_frame = (sos_vaddr_t)__builtin_frame_address(1);
389 } 305 }
390 306
391 for(depth=0 ; depth < max_depth ; depth ++) 307 for(depth=0 ; depth < max_depth ; depth ++)
392 { 308 {
393 309
394 backtracer(callee_PC, caller_frame + 8, 310 backtracer(callee_PC, caller_frame + 8, depth, custom_arg);
395 311
396 312
397 if ( (caller_frame < stack_bottom) 313 if ( (caller_frame < stack_bottom)
398 || (caller_frame + 4 >= stack_botto 314 || (caller_frame + 4 >= stack_bottom + stack_size) )
399 return depth; 315 return depth;
400 316
401 317
402 callee_PC = *((sos_vaddr_t*) (caller_ 318 callee_PC = *((sos_vaddr_t*) (caller_frame + 4));
403 caller_frame = *((sos_vaddr_t*) caller_f 319 caller_frame = *((sos_vaddr_t*) caller_frame);
404 } 320 }
405 321
406 return depth; 322 return depth;
407 } 323 }