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 #include <hwcore/gdt.h> <<
027 #include <sos/uaccess.h> <<
028 026
029 #include "cpu_context.h" 027 #include "cpu_context.h"
030 028
031 029
032 030
033 031
034 032
035 033
036 034
037 035
038 036
039 037
040 038
041 039
042 040
043 041
044 042
045 struct sos_cpu_state { 043 struct sos_cpu_state {
046 044
047 045
048 046
049 sos_ui16_t gs; 047 sos_ui16_t gs;
050 sos_ui16_t fs; 048 sos_ui16_t fs;
051 sos_ui16_t es; 049 sos_ui16_t es;
052 sos_ui16_t ds; 050 sos_ui16_t ds;
053 sos_ui16_t cpl0_ss; 051 sos_ui16_t cpl0_ss;
054 052
055 053
056 sos_ui16_t alignment_padding; 054 sos_ui16_t alignment_padding;
057 sos_ui32_t eax; 055 sos_ui32_t eax;
058 sos_ui32_t ebx; 056 sos_ui32_t ebx;
059 sos_ui32_t ecx; 057 sos_ui32_t ecx;
060 sos_ui32_t edx; 058 sos_ui32_t edx;
061 sos_ui32_t esi; 059 sos_ui32_t esi;
062 sos_ui32_t edi; 060 sos_ui32_t edi;
063 sos_ui32_t ebp; 061 sos_ui32_t ebp;
064 062
065 063
066 sos_ui32_t error_code; 064 sos_ui32_t error_code;
067 sos_vaddr_t eip; 065 sos_vaddr_t eip;
068 sos_ui32_t cs; 066 sos_ui32_t cs;
069 067
070 sos_ui32_t eflags; 068 sos_ui32_t eflags;
071 069
072 070
073 } __attribute__((packed)); 071 } __attribute__((packed));
074 072
075 073
076 074
077 075
078 076
079 077
080 078
081 079
082 080
083 081
084 082
085 083
086 084
087 085
088 086
089 #define GET_CPU_CS_REGISTER_VALUE(pushed_ui32_ 087 #define GET_CPU_CS_REGISTER_VALUE(pushed_ui32_cs_value) \
090 ( (pushed_ui32_cs_value) & 0xffff ) 088 ( (pushed_ui32_cs_value) & 0xffff )
091 089
092 090
093 091
094 092
095 093
096 struct sos_cpu_kstate 094 struct sos_cpu_kstate
097 { 095 {
098 struct sos_cpu_state regs; 096 struct sos_cpu_state regs;
099 } __attribute__((packed)); 097 } __attribute__((packed));
100 098
101 099
102 100
103 <<
104 <<
105 <<
106 <<
107 <<
108 <<
109 <<
110 struct sos_cpu_ustate <<
111 { <<
112 struct sos_cpu_state regs; <<
113 struct <<
114 { <<
115 sos_ui32_t cpl3_esp; <<
116 sos_ui16_t cpl3_ss; <<
117 }; <<
118 } __attribute__((packed)); <<
119 <<
120 <<
121 <<
122 <<
123 <<
124 <<
125 <<
126 <<
127 <<
128 <<
129 <<
130 <<
131 struct x86_tss { <<
132 <<
133 <<
134 <<
135 <<
136 <<
137 <<
138 <<
139 <<
140 <<
141 <<
142 sos_ui16_t back_link; <<
143 <<
144 sos_ui16_t reserved1; <<
145 <<
146 <<
147 sos_vaddr_t esp0; <<
148 sos_ui16_t ss0; <<
149 <<
150 sos_ui16_t reserved2; <<
151 <<
152 <<
153 sos_vaddr_t esp1; <<
154 sos_ui16_t ss1; <<
155 <<
156 sos_ui16_t reserved3; <<
157 <<
158 <<
159 sos_vaddr_t esp2; <<
160 sos_ui16_t ss2; <<
161 <<
162 sos_ui16_t reserved4; <<
163 <<
164 <<
165 sos_vaddr_t cr3; <<
166 sos_vaddr_t eip; <<
167 sos_ui32_t eflags; <<
168 sos_ui32_t eax; <<
169 sos_ui32_t ecx; <<
170 sos_ui32_t edx; <<
171 sos_ui32_t ebx; <<
172 sos_ui32_t esp; <<
173 sos_ui32_t ebp; <<
174 sos_ui32_t esi; <<
175 sos_ui32_t edi; <<
176 <<
177 <<
178 sos_ui16_t es; <<
179 sos_ui16_t reserved5; <<
180 <<
181 <<
182 sos_ui16_t cs; <<
183 sos_ui16_t reserved6; <<
184 <<
185 <<
186 sos_ui16_t ss; <<
187 sos_ui16_t reserved7; <<
188 <<
189 <<
190 sos_ui16_t ds; <<
191 sos_ui16_t reserved8; <<
192 <<
193 <<
194 sos_ui16_t fs; <<
195 sos_ui16_t reserved9; <<
196 <<
197 <<
198 sos_ui16_t gs; <<
199 sos_ui16_t reserved10; <<
200 <<
201 <<
202 sos_ui16_t ldtr; <<
203 sos_ui16_t reserved11; <<
204 <<
205 <<
206 sos_ui16_t debug_trap_flag :1; <<
207 sos_ui16_t reserved12 :15; <<
208 sos_ui16_t iomap_base_addr; <<
209 <<
210 <<
211 } __attribute__((packed, aligned(128))); <<
212 <<
213 <<
214 static struct x86_tss kernel_tss; <<
215 <<
216 <<
217 sos_ret_t sos_cpu_context_subsystem_setup() <<
218 { <<
219 <<
220 memset(&kernel_tss, 0x0, sizeof(kernel_tss)) <<
221 <<
222 <<
223 <<
224 <<
225 <<
226 <<
227 <<
228 <<
229 <<
230 <<
231 <<
232 kernel_tss.ss0 = SOS_BUILD_SEGMENT_REG_VALUE <<
233 <<
234 <<
235 sos_gdt_register_kernel_tss((sos_vaddr_t) &k <<
236 <<
237 return SOS_OK; <<
238 } <<
239 <<
240 <<
241 <<
242 101
243 102
244 103
245 104
246 static void core_routine (sos_cpu_kstate_funct 105 static void core_routine (sos_cpu_kstate_function_arg1_t *start_func,
247 sos_ui32_t start_arg 106 sos_ui32_t start_arg,
248 sos_cpu_kstate_funct 107 sos_cpu_kstate_function_arg1_t *exit_func,
249 sos_ui32_t exit_arg) 108 sos_ui32_t exit_arg)
250 __attribute__((noreturn)); 109 __attribute__((noreturn));
251 110
252 static void core_routine (sos_cpu_kstate_funct 111 static void core_routine (sos_cpu_kstate_function_arg1_t *start_func,
253 sos_ui32_t start_arg 112 sos_ui32_t start_arg,
254 sos_cpu_kstate_funct 113 sos_cpu_kstate_function_arg1_t *exit_func,
255 sos_ui32_t exit_arg) 114 sos_ui32_t exit_arg)
256 { 115 {
257 start_func(start_arg); 116 start_func(start_arg);
258 exit_func(exit_arg); 117 exit_func(exit_arg);
259 118
260 SOS_ASSERT_FATAL(! "The exit function of the 119 SOS_ASSERT_FATAL(! "The exit function of the thread should NOT return !");
261 for(;;); 120 for(;;);
262 } 121 }
263 122
264 123
265 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_s 124 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_state **ctxt,
266 sos_cpu_kstate_f 125 sos_cpu_kstate_function_arg1_t *start_func,
267 sos_ui32_t star 126 sos_ui32_t start_arg,
268 sos_vaddr_t stac 127 sos_vaddr_t stack_bottom,
269 sos_size_t stac 128 sos_size_t stack_size,
270 sos_cpu_kstate_f 129 sos_cpu_kstate_function_arg1_t *exit_func,
271 sos_ui32_t exit 130 sos_ui32_t exit_arg)
272 { 131 {
273 132
274 struct sos_cpu_kstate *kctxt; 133 struct sos_cpu_kstate *kctxt;
275 134
276 135
277 136
278 137
279 138
280 139
281 140
282 141
283 142
284 143
285 144
286 145
287 146
288 147
289 148
290 149
291 150
292 151
293 152
294 153
295 154
296 155
297 156
298 sos_vaddr_t tmp_vaddr = stack_bottom + stack 157 sos_vaddr_t tmp_vaddr = stack_bottom + stack_size;
299 sos_ui32_t *stack = (sos_ui32_t*)tmp_vaddr; 158 sos_ui32_t *stack = (sos_ui32_t*)tmp_vaddr;
300 159
301 160
302 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS 161 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS
303 memset((void*)stack_bottom, SOS_CPU_STATE_ST 162 memset((void*)stack_bottom, SOS_CPU_STATE_STACK_POISON, stack_size);
304 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STAC 163 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
305 sos_cpu_state_prepare_detect_kernel_stack_ov 164 sos_cpu_state_prepare_detect_kernel_stack_overflow(stack_bottom, stack_size);
306 #endif 165 #endif
307 166
308 167
309 168
310 *(--stack) = exit_arg; 169 *(--stack) = exit_arg;
311 *(--stack) = (sos_ui32_t)exit_func; 170 *(--stack) = (sos_ui32_t)exit_func;
312 *(--stack) = start_arg; 171 *(--stack) = start_arg;
313 *(--stack) = (sos_ui32_t)start_func; 172 *(--stack) = (sos_ui32_t)start_func;
314 *(--stack) = 0; 173 *(--stack) = 0;
315 174
316 175
317 176
318 177
319 178
320 179
321 180
322 181
323 182
324 tmp_vaddr = ((sos_vaddr_t)stack) - sizeof(s 183 tmp_vaddr = ((sos_vaddr_t)stack) - sizeof(struct sos_cpu_kstate);
325 kctxt = (struct sos_cpu_kstate*)tmp_vaddr; 184 kctxt = (struct sos_cpu_kstate*)tmp_vaddr;
326 185
327 186
328 memset(kctxt, 0x0, sizeof(struct sos_cpu_kst 187 memset(kctxt, 0x0, sizeof(struct sos_cpu_kstate));
329 188
330 189
331 190
332 kctxt->regs.eip = (sos_ui32_t)core_routine; 191 kctxt->regs.eip = (sos_ui32_t)core_routine;
333 192
334 193
335 kctxt->regs.cs 194 kctxt->regs.cs
336 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO 195 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE);
337 kctxt->regs.ds 196 kctxt->regs.ds
338 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO 197 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA);
339 kctxt->regs.es 198 kctxt->regs.es
340 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO 199 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA);
341 kctxt->regs.cpl0_ss 200 kctxt->regs.cpl0_ss
342 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO 201 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA);
343 202
344 203
345 204
346 kctxt->regs.eflags = (1 << 9); 205 kctxt->regs.eflags = (1 << 9);
347 206
348 207
349 *ctxt = (struct sos_cpu_state*) kctxt; 208 *ctxt = (struct sos_cpu_state*) kctxt;
350 209
351 return SOS_OK; 210 return SOS_OK;
352 } 211 }
353 212
354 213
355 <<
356 <<
357 <<
358 <<
359 <<
360 <<
361 static sos_ret_t cpu_ustate_init(struct sos_cp <<
362 const struct <<
363 sos_uaddr_t <<
364 sos_ui32_t <<
365 sos_ui32_t <<
366 sos_uaddr_t <<
367 sos_vaddr_t <<
368 sos_size_t <<
369 { <<
370 <<
371 struct sos_cpu_ustate *uctxt; <<
372 <<
373 <<
374 <<
375 <<
376 <<
377 <<
378 <<
379 sos_vaddr_t uctxt_vaddr = kernel_stack_botto <<
380 + kernel_stack_si <<
381 - sizeof(struct s <<
382 uctxt = (struct sos_cpu_ustate*)uctxt_vaddr; <<
383 <<
384 if (model_uctxt && !sos_cpu_context_is_in_us <<
385 return -SOS_EINVAL; <<
386 <<
387 <<
388 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS <<
389 memset((void*)kernel_stack_bottom, <<
390 SOS_CPU_STATE_STACK_POISON, <<
391 kernel_stack_size); <<
392 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STAC <<
393 sos_cpu_state_prepare_detect_kernel_stack_ov <<
394 <<
395 #endif <<
396 <<
397 <<
398 <<
399 <<
400 <<
401 <<
402 <<
403 <<
404 if (! model_uctxt) <<
405 { <<
406 memset(uctxt, 0x0, sizeof(struct sos_cpu <<
407 <<
408 <<
409 <<
410 uctxt->regs.eip = (sos_ui32_t)user_start <<
411 <<
412 <<
413 uctxt->cpl3_esp = user_initial_SP; <<
414 } <<
415 else <<
416 memcpy(uctxt, model_uctxt, sizeof(struct s <<
417 <<
418 <<
419 <<
420 uctxt->regs.eax = user_start_arg1; <<
421 <<
422 <<
423 if (! model_uctxt) <<
424 uctxt->regs.ebx = user_start_arg2; <<
425 <<
426 <<
427 uctxt->regs.cs <<
428 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
429 uctxt->regs.ds <<
430 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
431 uctxt->regs.es <<
432 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
433 uctxt->cpl3_ss <<
434 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
435 <<
436 <<
437 <<
438 <<
439 <<
440 uctxt->regs.cpl0_ss <<
441 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
442 <<
443 <<
444 <<
445 <<
446 uctxt->regs.eflags = (1 << 9); <<
447 <<
448 <<
449 *ctxt = (struct sos_cpu_state*) uctxt; <<
450 <<
451 return SOS_OK; <<
452 } <<
453 <<
454 <<
455 sos_ret_t sos_cpu_ustate_init(struct sos_cpu_s <<
456 sos_uaddr_t use <<
457 sos_ui32_t use <<
458 sos_ui32_t use <<
459 sos_uaddr_t use <<
460 sos_vaddr_t ker <<
461 sos_size_t ker <<
462 { <<
463 return cpu_ustate_init(ctxt, NULL, <<
464 user_start_PC, <<
465 user_start_arg1, user <<
466 user_initial_SP, <<
467 kernel_stack_bottom, <<
468 } <<
469 <<
470 <<
471 sos_ret_t sos_cpu_ustate_duplicate(struct sos_ <<
472 const struc <<
473 sos_ui32_t <<
474 sos_vaddr_t <<
475 sos_size_t <<
476 { <<
477 return cpu_ustate_init(ctxt, model_uctxt, <<
478 0, <<
479 user_retval, <<
480 0, <<
481 kernel_stack_bottom, <<
482 } <<
483 <<
484 <<
485 sos_ret_t <<
486 sos_cpu_context_is_in_user_mode(const struct s <<
487 { <<
488 <<
489 <<
490 switch (GET_CPU_CS_REGISTER_VALUE(ctxt->cs)) <<
491 { <<
492 case SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, <<
493 return TRUE; <<
494 break; <<
495 <<
496 case SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, <<
497 return FALSE; <<
498 break; <<
499 <<
500 default: <<
501 SOS_FATAL_ERROR("Invalid saved context C <<
502 (unsigned) GET_CPU_CS_RE <<
503 SOS_BUILD_SEGMENT_REG_VA <<
504 SOS_BUILD_SEGMENT_REG_VA <<
505 break; <<
506 } <<
507 <<
508 <<
509 return -SOS_EFATAL; <<
510 } <<
511 <<
512 <<
513 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_ 214 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
514 void 215 void
515 sos_cpu_state_prepare_detect_kernel_stack_over 216 sos_cpu_state_prepare_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
516 217 sos_vaddr_t stack_bottom,
517 218 sos_size_t stack_size)
518 { 219 {
519 sos_size_t poison_size = SOS_CPU_STATE_DETEC 220 sos_size_t poison_size = SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW;
520 if (poison_size > stack_size) 221 if (poison_size > stack_size)
521 poison_size = stack_size; 222 poison_size = stack_size;
522 223
523 memset((void*)stack_bottom, SOS_CPU_STATE_ST 224 memset((void*)stack_bottom, SOS_CPU_STATE_STACK_POISON, poison_size);
524 } 225 }
525 226
526 227
527 void 228 void
528 sos_cpu_state_detect_kernel_stack_overflow(con 229 sos_cpu_state_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
529 sos 230 sos_vaddr_t stack_bottom,
530 sos 231 sos_size_t stack_size)
531 { 232 {
532 unsigned char *c; 233 unsigned char *c;
533 int i; 234 int i;
534 235
535 236
536 237
537 238
538 239
539 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stac 240 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stack_bottom);
540 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeo 241 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeof(struct sos_cpu_kstate)
541 <= stack_bottom + stack_siz 242 <= stack_bottom + stack_size);
542 243
543 244
544 for (c = (unsigned char*) stack_bottom, i = 245 for (c = (unsigned char*) stack_bottom, i = 0 ;
545 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_ 246 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) && (i < stack_size) ;
546 c++, i++) 247 c++, i++)
547 { 248 {
548 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POI 249 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POISON == *c);
549 } 250 }
550 } 251 }
551 #endif 252 #endif
552 253
553 254
554 255
555 256
556 257
557 258
558 259
559 sos_vaddr_t sos_cpu_context_get_PC(const struc 260 sos_vaddr_t sos_cpu_context_get_PC(const struct sos_cpu_state *ctxt)
560 { 261 {
561 SOS_ASSERT_FATAL(NULL != ctxt); 262 SOS_ASSERT_FATAL(NULL != ctxt);
562 263
563 264
564 265
565 return ctxt->eip; 266 return ctxt->eip;
566 } 267 }
567 268
568 269
569 sos_vaddr_t sos_cpu_context_get_SP(const struc 270 sos_vaddr_t sos_cpu_context_get_SP(const struct sos_cpu_state *ctxt)
570 { 271 {
571 SOS_ASSERT_FATAL(NULL != ctxt); 272 SOS_ASSERT_FATAL(NULL != ctxt);
572 273
573 <<
574 <<
575 <<
576 if (TRUE == sos_cpu_context_is_in_user_mode( <<
577 { <<
578 struct sos_cpu_ustate * uctxt = (struct <<
579 return uctxt->cpl3_esp; <<
580 } <<
581 <<
582 274
583 275
584 276
585 return (sos_vaddr_t)ctxt; 277 return (sos_vaddr_t)ctxt;
586 } 278 }
587 279
588 280
589 sos_ret_t <<
590 sos_cpu_context_set_EX_return_address(struct s <<
591 sos_vadd <<
592 { <<
593 ctxt->eip = ret_vaddr; <<
594 return SOS_OK; <<
595 } <<
596 <<
597 <<
598 void sos_cpu_context_dump(const struct sos_cpu 281 void sos_cpu_context_dump(const struct sos_cpu_state *ctxt)
599 { 282 {
600 char buf[128]; 283 char buf[128];
601 <<
602 snprintf(buf, sizeof(buf), 284 snprintf(buf, sizeof(buf),
603 "CPU: eip=%x esp0=%x eflags=%x cs=% !! 285 "CPU: eip=%x esp=%x eflags=%x cs=%x ds=%x ss=%x err=%x",
604 (unsigned)ctxt->eip, (unsigned)ctxt 286 (unsigned)ctxt->eip, (unsigned)ctxt, (unsigned)ctxt->eflags,
605 (unsigned)GET_CPU_CS_REGISTER_VALUE 287 (unsigned)GET_CPU_CS_REGISTER_VALUE(ctxt->cs), (unsigned)ctxt->ds,
606 (unsigned)ctxt->cpl0_ss, 288 (unsigned)ctxt->cpl0_ss,
607 (unsigned)ctxt->error_code); 289 (unsigned)ctxt->error_code);
608 if (TRUE == sos_cpu_context_is_in_user_mode( <<
609 { <<
610 struct sos_cpu_ustate * uctxt = (struct <<
611 snprintf(buf, sizeof(buf), <<
612 "%s esp3=%x ss3=%x", <<
613 buf, (unsigned)uctxt->cpl3_esp, <<
614 } <<
615 else <<
616 snprintf(buf, sizeof(buf), "%s [KERNEL MOD <<
617 <<
618 sos_bochs_putstring(buf); sos_bochs_putstrin 290 sos_bochs_putstring(buf); sos_bochs_putstring("\n");
619 sos_x86_videomem_putstring(23, 0, 291 sos_x86_videomem_putstring(23, 0,
620 SOS_X86_VIDEO_FG_ !! 292 SOS_X86_VIDEO_FG_BLACK | SOS_X86_VIDEO_BG_LTGRAY,
621 buf); !! 293 buf);
622 } 294 }
623 295
624 296
625 297
626 298
627 299
628 300
629 301
630 sos_ui32_t sos_cpu_context_get_EX_info(const s 302 sos_ui32_t sos_cpu_context_get_EX_info(const struct sos_cpu_state *ctxt)
631 { 303 {
632 SOS_ASSERT_FATAL(NULL != ctxt); 304 SOS_ASSERT_FATAL(NULL != ctxt);
633 return ctxt->error_code; 305 return ctxt->error_code;
634 } 306 }
635 307
636 308
637 sos_vaddr_t 309 sos_vaddr_t
638 sos_cpu_context_get_EX_faulting_vaddr(const st 310 sos_cpu_context_get_EX_faulting_vaddr(const struct sos_cpu_state *ctxt)
639 { 311 {
640 sos_ui32_t cr2; 312 sos_ui32_t cr2;
641 313
642 314
643 315
644 316
645 317
646 318
647 319
648 320
649 321
650 322
651 323
652 324
653 325
654 326
655 asm volatile ("movl %%cr2, %0" 327 asm volatile ("movl %%cr2, %0"
656 :"=r"(cr2) 328 :"=r"(cr2)
657 : ); 329 : );
658 330
659 return cr2; 331 return cr2;
660 } 332 }
661 333
662 334
663 335
664 <<
665 <<
666 <<
667 <<
668 <<
669 <<
670 <<
671 <<
672 <<
673 <<
674 <<
675 <<
676 <<
677 <<
678 inline <<
679 sos_ret_t sos_syscall_get3args(const struct so <<
680 unsign <<
681 unsign <<
682 unsign <<
683 { <<
684 *arg1 = user_ctxt->ebx; <<
685 *arg2 = user_ctxt->ecx; <<
686 *arg3 = user_ctxt->edx; <<
687 return SOS_OK; <<
688 } <<
689 <<
690 <<
691 sos_ret_t sos_syscall_get1arg(const struct sos <<
692 unsigne <<
693 { <<
694 unsigned int unused; <<
695 return sos_syscall_get3args(user_ctxt, arg1, <<
696 } <<
697 <<
698 <<
699 sos_ret_t sos_syscall_get2args(const struct so <<
700 unsign <<
701 unsign <<
702 { <<
703 unsigned int unused; <<
704 return sos_syscall_get3args(user_ctxt, arg1, <<
705 } <<
706 <<
707 <<
708 <<
709 <<
710 <<
711 <<
712 <<
713 sos_ret_t sos_syscall_get4args(const struct so <<
714 unsign <<
715 unsign <<
716 unsign <<
717 unsign <<
718 { <<
719 sos_uaddr_t uaddr_other_args; <<
720 unsigned int other_args[2]; <<
721 sos_ret_t retval; <<
722 <<
723 <<
724 <<
725 retval = sos_syscall_get3args(user_ctxt, arg <<
726 (unsigned int <<
727 if (SOS_OK != retval) <<
728 return retval; <<
729 <<
730 <<
731 <<
732 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
733 (sos_uaddr_t)u <<
734 sizeof(other_a <<
735 if (sizeof(other_args) != retval) <<
736 return -SOS_EFAULT; <<
737 <<
738 *arg3 = other_args[0]; <<
739 *arg4 = other_args[1]; <<
740 return SOS_OK; <<
741 } <<
742 <<
743 <<
744 sos_ret_t sos_syscall_get5args(const struct so <<
745 unsign <<
746 unsign <<
747 unsign <<
748 unsign <<
749 unsign <<
750 { <<
751 sos_uaddr_t uaddr_other_args; <<
752 unsigned int other_args[3]; <<
753 sos_ret_t retval; <<
754 <<
755 <<
756 <<
757 retval = sos_syscall_get3args(user_ctxt, arg <<
758 (unsigned int <<
759 if (SOS_OK != retval) <<
760 return retval; <<
761 <<
762 <<
763 <<
764 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
765 (sos_uaddr_t)u <<
766 sizeof(other_a <<
767 if (sizeof(other_args) != retval) <<
768 return -SOS_EFAULT; <<
769 <<
770 *arg3 = other_args[0]; <<
771 *arg4 = other_args[1]; <<
772 *arg5 = other_args[2]; <<
773 return SOS_OK; <<
774 } <<
775 <<
776 <<
777 sos_ret_t sos_syscall_get6args(const struct so <<
778 unsign <<
779 unsign <<
780 unsign <<
781 unsign <<
782 unsign <<
783 unsign <<
784 { <<
785 sos_uaddr_t uaddr_other_args; <<
786 unsigned int other_args[4]; <<
787 sos_ret_t retval; <<
788 <<
789 <<
790 <<
791 retval = sos_syscall_get3args(user_ctxt, arg <<
792 (unsigned int <<
793 if (SOS_OK != retval) <<
794 return retval; <<
795 <<
796 <<
797 <<
798 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
799 (sos_uaddr_t)u <<
800 sizeof(other_a <<
801 if (sizeof(other_args) != retval) <<
802 return -SOS_EFAULT; <<
803 <<
804 *arg3 = other_args[0]; <<
805 *arg4 = other_args[1]; <<
806 *arg5 = other_args[2]; <<
807 *arg6 = other_args[3]; <<
808 return SOS_OK; <<
809 } <<
810 <<
811 <<
812 sos_ret_t sos_syscall_get7args(const struct so <<
813 unsign <<
814 unsign <<
815 unsign <<
816 unsign <<
817 unsign <<
818 unsign <<
819 unsign <<
820 { <<
821 sos_uaddr_t uaddr_other_args; <<
822 unsigned int other_args[5]; <<
823 sos_ret_t retval; <<
824 <<
825 <<
826 <<
827 retval = sos_syscall_get3args(user_ctxt, arg <<
828 (unsigned int <<
829 if (SOS_OK != retval) <<
830 return retval; <<
831 <<
832 <<
833 <<
834 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
835 (sos_uaddr_t)u <<
836 sizeof(other_a <<
837 if (sizeof(other_args) != retval) <<
838 return -SOS_EFAULT; <<
839 <<
840 *arg3 = other_args[0]; <<
841 *arg4 = other_args[1]; <<
842 *arg5 = other_args[2]; <<
843 *arg6 = other_args[3]; <<
844 *arg7 = other_args[4]; <<
845 return SOS_OK; <<
846 } <<
847 <<
848 <<
849 sos_ret_t sos_syscall_get8args(const struct so <<
850 unsign <<
851 unsign <<
852 unsign <<
853 unsign <<
854 unsign <<
855 unsign <<
856 unsign <<
857 unsign <<
858 { <<
859 sos_uaddr_t uaddr_other_args; <<
860 unsigned int other_args[6]; <<
861 sos_ret_t retval; <<
862 <<
863 <<
864 <<
865 retval = sos_syscall_get3args(user_ctxt, arg <<
866 (unsigned int <<
867 if (SOS_OK != retval) <<
868 return retval; <<
869 <<
870 <<
871 <<
872 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
873 (sos_uaddr_t)u <<
874 sizeof(other_a <<
875 if (sizeof(other_args) != retval) <<
876 return -SOS_EFAULT; <<
877 <<
878 *arg3 = other_args[0]; <<
879 *arg4 = other_args[1]; <<
880 *arg5 = other_args[2]; <<
881 *arg6 = other_args[3]; <<
882 *arg7 = other_args[4]; <<
883 *arg8 = other_args[5]; <<
884 return SOS_OK; <<
885 } <<
886 <<
887 <<
888 <<
889 336
890 337
891 338
892 339
893 sos_ui32_t sos_backtrace(const struct sos_cpu_ 340 sos_ui32_t sos_backtrace(const struct sos_cpu_state *cpu_state,
894 sos_ui32_t max_depth, 341 sos_ui32_t max_depth,
895 sos_vaddr_t stack_bot 342 sos_vaddr_t stack_bottom,
896 sos_size_t stack_size 343 sos_size_t stack_size,
897 sos_backtrace_callbac 344 sos_backtrace_callback_t * backtracer,
898 void *custom_arg) 345 void *custom_arg)
899 { 346 {
900 int depth; 347 int depth;
901 sos_vaddr_t callee_PC, caller_frame; 348 sos_vaddr_t callee_PC, caller_frame;
902 349
903 <<
904 if ((NULL != cpu_state) <<
905 && <<
906 (TRUE == sos_cpu_context_is_in_user_mode <<
907 { <<
908 return 0; <<
909 } <<
910 <<
911 350
912 351
913 352
914 353
915 354
916 355
917 356
918 357
919 358
920 359
921 360
922 361
923 362
924 363
925 364
926 365
927 366
928 367
929 368
930 369
931 370
932 371
933 372
934 373
935 374
936 375
937 376
938 377
939 378
940 if (cpu_state) 379 if (cpu_state)
941 { 380 {
942 callee_PC = cpu_state->eip; 381 callee_PC = cpu_state->eip;
943 caller_frame = cpu_state->ebp; 382 caller_frame = cpu_state->ebp;
944 } 383 }
945 else 384 else
946 { 385 {
947 386
948 callee_PC = (sos_vaddr_t)__builtin_re 387 callee_PC = (sos_vaddr_t)__builtin_return_address(0);
949 caller_frame = (sos_vaddr_t)__builtin_fr 388 caller_frame = (sos_vaddr_t)__builtin_frame_address(1);
950 } 389 }
951 390
952 for(depth=0 ; depth < max_depth ; depth ++) 391 for(depth=0 ; depth < max_depth ; depth ++)
953 { 392 {
954 393
955 backtracer(callee_PC, caller_frame + 8, 394 backtracer(callee_PC, caller_frame + 8, depth, custom_arg);
956 395
957 396
958 if ( (caller_frame < stack_bottom) 397 if ( (caller_frame < stack_bottom)
959 || (caller_frame + 4 >= stack_botto 398 || (caller_frame + 4 >= stack_bottom + stack_size) )
960 return depth; 399 return depth;
961 400
962 401
963 callee_PC = *((sos_vaddr_t*) (caller_ 402 callee_PC = *((sos_vaddr_t*) (caller_frame + 4));
964 caller_frame = *((sos_vaddr_t*) caller_f 403 caller_frame = *((sos_vaddr_t*) caller_frame);
965 } 404 }
966 405
967 return depth; 406 return depth;
968 } <<
969 <<
970 <<
971 <<
972 <<
973 <<
974 <<
975 <<
976 <<
977 <<
978 <<
979 <<
980 void <<
981 sos_cpu_context_update_kernel_tss(struct sos_c <<
982 { <<
983 <<
984 if (sos_cpu_context_is_in_user_mode(next_ctx <<
985 { <<
986 <<
987 <<
988 <<
989 <<
990 <<
991 <<
992 <<
993 <<
994 <<
995 <<
996 <<
997 kernel_tss.esp0 = ((sos_vaddr_t)next_ctx <<
998 + sizeof(struct sos_cp <<
999 <<
1000 <<
1001 <<
1002 } <<
1003 else <<
1004 { <<
1005 <<
1006 <<
1007 } <<
1008 } 407 }