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 sos_ret_t sos_cpu_ustate_init(struct sos_cpu_s <<
356 sos_uaddr_t use <<
357 sos_ui32_t use <<
358 sos_ui32_t use <<
359 sos_uaddr_t use <<
360 sos_vaddr_t ker <<
361 sos_size_t ker <<
362 { <<
363 <<
364 struct sos_cpu_ustate *uctxt; <<
365 <<
366 <<
367 <<
368 <<
369 <<
370 <<
371 <<
372 sos_vaddr_t uctxt_vaddr = kernel_stack_botto <<
373 + kernel_stack_si <<
374 - sizeof(struct s <<
375 uctxt = (struct sos_cpu_ustate*)uctxt_vaddr; <<
376 <<
377 <<
378 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS <<
379 memset((void*)kernel_stack_bottom, <<
380 SOS_CPU_STATE_STACK_POISON, <<
381 kernel_stack_size); <<
382 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STAC <<
383 sos_cpu_state_prepare_detect_kernel_stack_ov <<
384 <<
385 #endif <<
386 <<
387 <<
388 <<
389 <<
390 <<
391 <<
392 <<
393 memset(uctxt, 0x0, sizeof(struct sos_cpu_ust <<
394 <<
395 <<
396 <<
397 uctxt->regs.eip = (sos_ui32_t)user_start_PC; <<
398 <<
399 <<
400 uctxt->cpl3_esp = user_initial_SP; <<
401 <<
402 <<
403 <<
404 uctxt->regs.eax = user_start_arg1; <<
405 uctxt->regs.ebx = user_start_arg2; <<
406 <<
407 <<
408 uctxt->regs.cs <<
409 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
410 uctxt->regs.ds <<
411 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
412 uctxt->regs.es <<
413 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
414 uctxt->cpl3_ss <<
415 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
416 <<
417 <<
418 <<
419 <<
420 <<
421 uctxt->regs.cpl0_ss <<
422 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
423 <<
424 <<
425 <<
426 <<
427 uctxt->regs.eflags = (1 << 9); <<
428 <<
429 <<
430 *ctxt = (struct sos_cpu_state*) uctxt; <<
431 <<
432 return SOS_OK; <<
433 } <<
434 <<
435 <<
436 sos_ret_t <<
437 sos_cpu_context_is_in_user_mode(const struct s <<
438 { <<
439 <<
440 <<
441 switch (GET_CPU_CS_REGISTER_VALUE(ctxt->cs)) <<
442 { <<
443 case SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, <<
444 return TRUE; <<
445 break; <<
446 <<
447 case SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, <<
448 return FALSE; <<
449 break; <<
450 <<
451 default: <<
452 SOS_FATAL_ERROR("Invalid saved context C <<
453 (unsigned) GET_CPU_CS_RE <<
454 SOS_BUILD_SEGMENT_REG_VA <<
455 SOS_BUILD_SEGMENT_REG_VA <<
456 break; <<
457 } <<
458 <<
459 <<
460 return -SOS_EFATAL; <<
461 } <<
462 <<
463 <<
464 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_ 214 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
465 void 215 void
466 sos_cpu_state_prepare_detect_kernel_stack_over 216 sos_cpu_state_prepare_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
467 217 sos_vaddr_t stack_bottom,
468 218 sos_size_t stack_size)
469 { 219 {
470 sos_size_t poison_size = SOS_CPU_STATE_DETEC 220 sos_size_t poison_size = SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW;
471 if (poison_size > stack_size) 221 if (poison_size > stack_size)
472 poison_size = stack_size; 222 poison_size = stack_size;
473 223
474 memset((void*)stack_bottom, SOS_CPU_STATE_ST 224 memset((void*)stack_bottom, SOS_CPU_STATE_STACK_POISON, poison_size);
475 } 225 }
476 226
477 227
478 void 228 void
479 sos_cpu_state_detect_kernel_stack_overflow(con 229 sos_cpu_state_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
480 sos 230 sos_vaddr_t stack_bottom,
481 sos 231 sos_size_t stack_size)
482 { 232 {
483 unsigned char *c; 233 unsigned char *c;
484 int i; 234 int i;
485 235
486 236
487 237
488 238
489 239
490 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stac 240 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stack_bottom);
491 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeo 241 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeof(struct sos_cpu_kstate)
492 <= stack_bottom + stack_siz 242 <= stack_bottom + stack_size);
493 243
494 244
495 for (c = (unsigned char*) stack_bottom, i = 245 for (c = (unsigned char*) stack_bottom, i = 0 ;
496 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_ 246 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) && (i < stack_size) ;
497 c++, i++) 247 c++, i++)
498 { 248 {
499 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POI 249 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POISON == *c);
500 } 250 }
501 } 251 }
502 #endif 252 #endif
503 253
504 254
505 255
506 256
507 257
508 258
509 259
510 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)
511 { 261 {
512 SOS_ASSERT_FATAL(NULL != ctxt); 262 SOS_ASSERT_FATAL(NULL != ctxt);
513 263
514 264
515 265
516 return ctxt->eip; 266 return ctxt->eip;
517 } 267 }
518 268
519 269
520 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)
521 { 271 {
522 SOS_ASSERT_FATAL(NULL != ctxt); 272 SOS_ASSERT_FATAL(NULL != ctxt);
523 273
524 <<
525 <<
526 <<
527 if (TRUE == sos_cpu_context_is_in_user_mode( <<
528 { <<
529 struct sos_cpu_ustate * uctxt = (struct <<
530 return uctxt->cpl3_esp; <<
531 } <<
532 <<
533 274
534 275
535 276
536 return (sos_vaddr_t)ctxt; 277 return (sos_vaddr_t)ctxt;
537 } 278 }
538 279
539 280
540 sos_ret_t <<
541 sos_cpu_context_set_EX_return_address(struct s <<
542 sos_vadd <<
543 { <<
544 ctxt->eip = ret_vaddr; <<
545 return SOS_OK; <<
546 } <<
547 <<
548 <<
549 void sos_cpu_context_dump(const struct sos_cpu 281 void sos_cpu_context_dump(const struct sos_cpu_state *ctxt)
550 { 282 {
551 char buf[128]; 283 char buf[128];
552 <<
553 snprintf(buf, sizeof(buf), 284 snprintf(buf, sizeof(buf),
554 "CPU: eip=%x esp0=%x eflags=%x cs=% !! 285 "CPU: eip=%x esp=%x eflags=%x cs=%x ds=%x ss=%x err=%x",
555 (unsigned)ctxt->eip, (unsigned)ctxt 286 (unsigned)ctxt->eip, (unsigned)ctxt, (unsigned)ctxt->eflags,
556 (unsigned)GET_CPU_CS_REGISTER_VALUE 287 (unsigned)GET_CPU_CS_REGISTER_VALUE(ctxt->cs), (unsigned)ctxt->ds,
557 (unsigned)ctxt->cpl0_ss, 288 (unsigned)ctxt->cpl0_ss,
558 (unsigned)ctxt->error_code); 289 (unsigned)ctxt->error_code);
559 if (TRUE == sos_cpu_context_is_in_user_mode( <<
560 { <<
561 struct sos_cpu_ustate * uctxt = (struct <<
562 snprintf(buf, sizeof(buf), <<
563 "%s esp3=%x ss3=%x", <<
564 buf, (unsigned)uctxt->cpl3_esp, <<
565 } <<
566 else <<
567 snprintf(buf, sizeof(buf), "%s [KERNEL MOD <<
568 <<
569 sos_bochs_putstring(buf); sos_bochs_putstrin 290 sos_bochs_putstring(buf); sos_bochs_putstring("\n");
570 sos_x86_videomem_putstring(23, 0, 291 sos_x86_videomem_putstring(23, 0,
571 SOS_X86_VIDEO_FG_ !! 292 SOS_X86_VIDEO_FG_BLACK | SOS_X86_VIDEO_BG_LTGRAY,
572 buf); !! 293 buf);
573 } 294 }
574 295
575 296
576 297
577 298
578 299
579 300
580 301
581 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)
582 { 303 {
583 SOS_ASSERT_FATAL(NULL != ctxt); 304 SOS_ASSERT_FATAL(NULL != ctxt);
584 return ctxt->error_code; 305 return ctxt->error_code;
585 } 306 }
586 307
587 308
588 sos_vaddr_t 309 sos_vaddr_t
589 sos_cpu_context_get_EX_faulting_vaddr(const st 310 sos_cpu_context_get_EX_faulting_vaddr(const struct sos_cpu_state *ctxt)
590 { 311 {
591 sos_ui32_t cr2; 312 sos_ui32_t cr2;
592 313
593 314
594 315
595 316
596 317
597 318
598 319
599 320
600 321
601 322
602 323
603 324
604 325
605 326
606 asm volatile ("movl %%cr2, %0" 327 asm volatile ("movl %%cr2, %0"
607 :"=r"(cr2) 328 :"=r"(cr2)
608 : ); 329 : );
609 330
610 return cr2; 331 return cr2;
611 } 332 }
612 333
613 334
614 335
615 <<
616 <<
617 <<
618 <<
619 <<
620 <<
621 <<
622 <<
623 <<
624 <<
625 <<
626 <<
627 <<
628 <<
629 inline <<
630 sos_ret_t sos_syscall_get3args(const struct so <<
631 unsign <<
632 unsign <<
633 unsign <<
634 { <<
635 *arg1 = user_ctxt->ebx; <<
636 *arg2 = user_ctxt->ecx; <<
637 *arg3 = user_ctxt->edx; <<
638 return SOS_OK; <<
639 } <<
640 <<
641 <<
642 sos_ret_t sos_syscall_get1arg(const struct sos <<
643 unsigne <<
644 { <<
645 unsigned int unused; <<
646 return sos_syscall_get3args(user_ctxt, arg1, <<
647 } <<
648 <<
649 <<
650 sos_ret_t sos_syscall_get2args(const struct so <<
651 unsign <<
652 unsign <<
653 { <<
654 unsigned int unused; <<
655 return sos_syscall_get3args(user_ctxt, arg1, <<
656 } <<
657 <<
658 <<
659 <<
660 <<
661 <<
662 <<
663 <<
664 sos_ret_t sos_syscall_get4args(const struct so <<
665 unsign <<
666 unsign <<
667 unsign <<
668 unsign <<
669 { <<
670 sos_uaddr_t uaddr_other_args; <<
671 unsigned int other_args[2]; <<
672 sos_ret_t retval; <<
673 <<
674 <<
675 <<
676 retval = sos_syscall_get3args(user_ctxt, arg <<
677 (unsigned int <<
678 if (SOS_OK != retval) <<
679 return retval; <<
680 <<
681 <<
682 <<
683 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
684 (sos_uaddr_t)u <<
685 sizeof(other_a <<
686 if (sizeof(other_args) != retval) <<
687 return -SOS_EFAULT; <<
688 <<
689 *arg3 = other_args[0]; <<
690 *arg4 = other_args[1]; <<
691 return SOS_OK; <<
692 } <<
693 <<
694 <<
695 sos_ret_t sos_syscall_get5args(const struct so <<
696 unsign <<
697 unsign <<
698 unsign <<
699 unsign <<
700 unsign <<
701 { <<
702 sos_uaddr_t uaddr_other_args; <<
703 unsigned int other_args[3]; <<
704 sos_ret_t retval; <<
705 <<
706 <<
707 <<
708 retval = sos_syscall_get3args(user_ctxt, arg <<
709 (unsigned int <<
710 if (SOS_OK != retval) <<
711 return retval; <<
712 <<
713 <<
714 <<
715 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
716 (sos_uaddr_t)u <<
717 sizeof(other_a <<
718 if (sizeof(other_args) != retval) <<
719 return -SOS_EFAULT; <<
720 <<
721 *arg3 = other_args[0]; <<
722 *arg4 = other_args[1]; <<
723 *arg5 = other_args[2]; <<
724 return SOS_OK; <<
725 } <<
726 <<
727 <<
728 sos_ret_t sos_syscall_get6args(const struct so <<
729 unsign <<
730 unsign <<
731 unsign <<
732 unsign <<
733 unsign <<
734 unsign <<
735 { <<
736 sos_uaddr_t uaddr_other_args; <<
737 unsigned int other_args[4]; <<
738 sos_ret_t retval; <<
739 <<
740 <<
741 <<
742 retval = sos_syscall_get3args(user_ctxt, arg <<
743 (unsigned int <<
744 if (SOS_OK != retval) <<
745 return retval; <<
746 <<
747 <<
748 <<
749 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
750 (sos_uaddr_t)u <<
751 sizeof(other_a <<
752 if (sizeof(other_args) != retval) <<
753 return -SOS_EFAULT; <<
754 <<
755 *arg3 = other_args[0]; <<
756 *arg4 = other_args[1]; <<
757 *arg5 = other_args[2]; <<
758 *arg6 = other_args[3]; <<
759 return SOS_OK; <<
760 } <<
761 <<
762 <<
763 sos_ret_t sos_syscall_get7args(const struct so <<
764 unsign <<
765 unsign <<
766 unsign <<
767 unsign <<
768 unsign <<
769 unsign <<
770 unsign <<
771 { <<
772 sos_uaddr_t uaddr_other_args; <<
773 unsigned int other_args[5]; <<
774 sos_ret_t retval; <<
775 <<
776 <<
777 <<
778 retval = sos_syscall_get3args(user_ctxt, arg <<
779 (unsigned int <<
780 if (SOS_OK != retval) <<
781 return retval; <<
782 <<
783 <<
784 <<
785 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
786 (sos_uaddr_t)u <<
787 sizeof(other_a <<
788 if (sizeof(other_args) != retval) <<
789 return -SOS_EFAULT; <<
790 <<
791 *arg3 = other_args[0]; <<
792 *arg4 = other_args[1]; <<
793 *arg5 = other_args[2]; <<
794 *arg6 = other_args[3]; <<
795 *arg7 = other_args[4]; <<
796 return SOS_OK; <<
797 } <<
798 <<
799 <<
800 sos_ret_t sos_syscall_get8args(const struct so <<
801 unsign <<
802 unsign <<
803 unsign <<
804 unsign <<
805 unsign <<
806 unsign <<
807 unsign <<
808 unsign <<
809 { <<
810 sos_uaddr_t uaddr_other_args; <<
811 unsigned int other_args[6]; <<
812 sos_ret_t retval; <<
813 <<
814 <<
815 <<
816 retval = sos_syscall_get3args(user_ctxt, arg <<
817 (unsigned int <<
818 if (SOS_OK != retval) <<
819 return retval; <<
820 <<
821 <<
822 <<
823 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
824 (sos_uaddr_t)u <<
825 sizeof(other_a <<
826 if (sizeof(other_args) != retval) <<
827 return -SOS_EFAULT; <<
828 <<
829 *arg3 = other_args[0]; <<
830 *arg4 = other_args[1]; <<
831 *arg5 = other_args[2]; <<
832 *arg6 = other_args[3]; <<
833 *arg7 = other_args[4]; <<
834 *arg8 = other_args[5]; <<
835 return SOS_OK; <<
836 } <<
837 <<
838 <<
839 <<
840 336
841 337
842 338
843 339
844 sos_ui32_t sos_backtrace(const struct sos_cpu_ 340 sos_ui32_t sos_backtrace(const struct sos_cpu_state *cpu_state,
845 sos_ui32_t max_depth, 341 sos_ui32_t max_depth,
846 sos_vaddr_t stack_bot 342 sos_vaddr_t stack_bottom,
847 sos_size_t stack_size 343 sos_size_t stack_size,
848 sos_backtrace_callbac 344 sos_backtrace_callback_t * backtracer,
849 void *custom_arg) 345 void *custom_arg)
850 { 346 {
851 int depth; 347 int depth;
852 sos_vaddr_t callee_PC, caller_frame; 348 sos_vaddr_t callee_PC, caller_frame;
853 349
854 <<
855 if ((NULL != cpu_state) <<
856 && <<
857 (TRUE == sos_cpu_context_is_in_user_mode <<
858 { <<
859 return 0; <<
860 } <<
861 <<
862 350
863 351
864 352
865 353
866 354
867 355
868 356
869 357
870 358
871 359
872 360
873 361
874 362
875 363
876 364
877 365
878 366
879 367
880 368
881 369
882 370
883 371
884 372
885 373
886 374
887 375
888 376
889 377
890 378
891 if (cpu_state) 379 if (cpu_state)
892 { 380 {
893 callee_PC = cpu_state->eip; 381 callee_PC = cpu_state->eip;
894 caller_frame = cpu_state->ebp; 382 caller_frame = cpu_state->ebp;
895 } 383 }
896 else 384 else
897 { 385 {
898 386
899 callee_PC = (sos_vaddr_t)__builtin_re 387 callee_PC = (sos_vaddr_t)__builtin_return_address(0);
900 caller_frame = (sos_vaddr_t)__builtin_fr 388 caller_frame = (sos_vaddr_t)__builtin_frame_address(1);
901 } 389 }
902 390
903 for(depth=0 ; depth < max_depth ; depth ++) 391 for(depth=0 ; depth < max_depth ; depth ++)
904 { 392 {
905 393
906 backtracer(callee_PC, caller_frame + 8, 394 backtracer(callee_PC, caller_frame + 8, depth, custom_arg);
907 395
908 396
909 if ( (caller_frame < stack_bottom) 397 if ( (caller_frame < stack_bottom)
910 || (caller_frame + 4 >= stack_botto 398 || (caller_frame + 4 >= stack_bottom + stack_size) )
911 return depth; 399 return depth;
912 400
913 401
914 callee_PC = *((sos_vaddr_t*) (caller_ 402 callee_PC = *((sos_vaddr_t*) (caller_frame + 4));
915 caller_frame = *((sos_vaddr_t*) caller_f 403 caller_frame = *((sos_vaddr_t*) caller_frame);
916 } 404 }
917 405
918 return depth; 406 return depth;
919 } <<
920 <<
921 <<
922 <<
923 <<
924 <<
925 <<
926 <<
927 <<
928 <<
929 <<
930 <<
931 void <<
932 sos_cpu_context_update_kernel_tss(struct sos_c <<
933 { <<
934 <<
935 if (sos_cpu_context_is_in_user_mode(next_ctx <<
936 { <<
937 <<
938 <<
939 <<
940 <<
941 <<
942 <<
943 <<
944 <<
945 <<
946 <<
947 <<
948 kernel_tss.esp0 = ((sos_vaddr_t)next_ctx <<
949 + sizeof(struct sos_cp <<
950 <<
951 <<
952 <<
953 } <<
954 else <<
955 { <<
956 <<
957 <<
958 } <<
959 } 407 }