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