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 sos_ret_t sos_cpu_ustate_init(struct sos_cpu_s !! 355
356 sos_uaddr_t use !! 356
357 sos_ui32_t use !! 357
358 sos_ui32_t use !! 358
359 sos_uaddr_t use !! 359
360 sos_vaddr_t ker !! 360
361 sos_size_t ker !! 361 static sos_ret_t cpu_ustate_init(struct sos_cpu_state **ctxt,
>> 362 const struct sos_cpu_state *model_uctxt,
>> 363 sos_uaddr_t user_start_PC,
>> 364 sos_ui32_t user_start_arg1,
>> 365 sos_ui32_t user_start_arg2,
>> 366 sos_uaddr_t user_initial_SP,
>> 367 sos_vaddr_t kernel_stack_bottom,
>> 368 sos_size_t kernel_stack_size)
362 { 369 {
363 370
364 struct sos_cpu_ustate *uctxt; 371 struct sos_cpu_ustate *uctxt;
365 372
366 373
367 374
368 375
369 376
370 377
371 378
372 sos_vaddr_t uctxt_vaddr = kernel_stack_botto 379 sos_vaddr_t uctxt_vaddr = kernel_stack_bottom
373 + kernel_stack_si 380 + kernel_stack_size
374 - sizeof(struct s 381 - sizeof(struct sos_cpu_ustate);
375 uctxt = (struct sos_cpu_ustate*)uctxt_vaddr; 382 uctxt = (struct sos_cpu_ustate*)uctxt_vaddr;
376 383
>> 384 if (model_uctxt && !sos_cpu_context_is_in_user_mode(model_uctxt))
>> 385 return -SOS_EINVAL;
>> 386
377 387
378 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS 388 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS
379 memset((void*)kernel_stack_bottom, 389 memset((void*)kernel_stack_bottom,
380 SOS_CPU_STATE_STACK_POISON, 390 SOS_CPU_STATE_STACK_POISON,
381 kernel_stack_size); 391 kernel_stack_size);
382 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STAC 392 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
383 sos_cpu_state_prepare_detect_kernel_stack_ov 393 sos_cpu_state_prepare_detect_kernel_stack_overflow(kernel_stack_bottom,
384 394 kernel_stack_size);
385 #endif 395 #endif
386 396
387 397
388 398
389 399
390 400
391 401
392 402
393 memset(uctxt, 0x0, sizeof(struct sos_cpu_ust !! 403
394 !! 404 if (! model_uctxt)
395 !! 405 {
396 !! 406 memset(uctxt, 0x0, sizeof(struct sos_cpu_ustate));
397 uctxt->regs.eip = (sos_ui32_t)user_start_PC; !! 407
398 !! 408
399 !! 409
400 uctxt->cpl3_esp = user_initial_SP; !! 410 uctxt->regs.eip = (sos_ui32_t)user_start_PC;
>> 411
>> 412
>> 413 uctxt->cpl3_esp = user_initial_SP;
>> 414 }
>> 415 else
>> 416 memcpy(uctxt, model_uctxt, sizeof(struct sos_cpu_ustate));
401 417
402 418
403 419
404 uctxt->regs.eax = user_start_arg1; 420 uctxt->regs.eax = user_start_arg1;
405 uctxt->regs.ebx = user_start_arg2; !! 421
>> 422
>> 423 if (! model_uctxt)
>> 424 uctxt->regs.ebx = user_start_arg2;
406 425
407 426
408 uctxt->regs.cs 427 uctxt->regs.cs
409 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO 428 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SOS_SEG_UCODE);
410 uctxt->regs.ds 429 uctxt->regs.ds
411 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO 430 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SOS_SEG_UDATA);
412 uctxt->regs.es 431 uctxt->regs.es
413 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO 432 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SOS_SEG_UDATA);
414 uctxt->cpl3_ss 433 uctxt->cpl3_ss
415 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO 434 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SOS_SEG_UDATA);
416 435
417 436
418 437
419 438
420 439
421 uctxt->regs.cpl0_ss 440 uctxt->regs.cpl0_ss
422 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO 441 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA);
423 442
424 443
425 444
426 445
427 uctxt->regs.eflags = (1 << 9); 446 uctxt->regs.eflags = (1 << 9);
428 447
429 448
430 *ctxt = (struct sos_cpu_state*) uctxt; 449 *ctxt = (struct sos_cpu_state*) uctxt;
431 450
432 return SOS_OK; 451 return SOS_OK;
>> 452 }
>> 453
>> 454
>> 455 sos_ret_t sos_cpu_ustate_init(struct sos_cpu_state **ctxt,
>> 456 sos_uaddr_t user_start_PC,
>> 457 sos_ui32_t user_start_arg1,
>> 458 sos_ui32_t user_start_arg2,
>> 459 sos_uaddr_t user_initial_SP,
>> 460 sos_vaddr_t kernel_stack_bottom,
>> 461 sos_size_t kernel_stack_size)
>> 462 {
>> 463 return cpu_ustate_init(ctxt, NULL,
>> 464 user_start_PC,
>> 465 user_start_arg1, user_start_arg2,
>> 466 user_initial_SP,
>> 467 kernel_stack_bottom, kernel_stack_size);
>> 468 }
>> 469
>> 470
>> 471 sos_ret_t sos_cpu_ustate_duplicate(struct sos_cpu_state **ctxt,
>> 472 const struct sos_cpu_state *model_uctxt,
>> 473 sos_ui32_t user_retval,
>> 474 sos_vaddr_t kernel_stack_bottom,
>> 475 sos_size_t kernel_stack_size)
>> 476 {
>> 477 return cpu_ustate_init(ctxt, model_uctxt,
>> 478 0,
>> 479 user_retval, 0,
>> 480 0,
>> 481 kernel_stack_bottom, kernel_stack_size);
433 } 482 }
434 483
435 484
436 sos_ret_t 485 sos_ret_t
437 sos_cpu_context_is_in_user_mode(const struct s 486 sos_cpu_context_is_in_user_mode(const struct sos_cpu_state *ctxt)
438 { 487 {
439 488
440 489
441 switch (GET_CPU_CS_REGISTER_VALUE(ctxt->cs)) 490 switch (GET_CPU_CS_REGISTER_VALUE(ctxt->cs))
442 { 491 {
443 case SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, 492 case SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SOS_SEG_UCODE):
444 return TRUE; 493 return TRUE;
445 break; 494 break;
446 495
447 case SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, 496 case SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE):
448 return FALSE; 497 return FALSE;
449 break; 498 break;
450 499
451 default: 500 default:
452 SOS_FATAL_ERROR("Invalid saved context C 501 SOS_FATAL_ERROR("Invalid saved context Code segment register: 0x%x (k=%x, u=%x) !",
453 (unsigned) GET_CPU_CS_RE 502 (unsigned) GET_CPU_CS_REGISTER_VALUE(ctxt->cs),
454 SOS_BUILD_SEGMENT_REG_VA 503 SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE),
455 SOS_BUILD_SEGMENT_REG_VA 504 SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SOS_SEG_UCODE));
456 break; 505 break;
457 } 506 }
458 507
459 508
460 return -SOS_EFATAL; 509 return -SOS_EFATAL;
461 } 510 }
462 511
463 512
464 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_ 513 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
465 void 514 void
466 sos_cpu_state_prepare_detect_kernel_stack_over 515 sos_cpu_state_prepare_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
467 516 sos_vaddr_t stack_bottom,
468 517 sos_size_t stack_size)
469 { 518 {
470 sos_size_t poison_size = SOS_CPU_STATE_DETEC 519 sos_size_t poison_size = SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW;
471 if (poison_size > stack_size) 520 if (poison_size > stack_size)
472 poison_size = stack_size; 521 poison_size = stack_size;
473 522
474 memset((void*)stack_bottom, SOS_CPU_STATE_ST 523 memset((void*)stack_bottom, SOS_CPU_STATE_STACK_POISON, poison_size);
475 } 524 }
476 525
477 526
478 void 527 void
479 sos_cpu_state_detect_kernel_stack_overflow(con 528 sos_cpu_state_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
480 sos 529 sos_vaddr_t stack_bottom,
481 sos 530 sos_size_t stack_size)
482 { 531 {
483 unsigned char *c; 532 unsigned char *c;
484 int i; 533 int i;
485 534
486 535
487 536
488 537
489 538
490 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stac 539 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stack_bottom);
491 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeo 540 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeof(struct sos_cpu_kstate)
492 <= stack_bottom + stack_siz 541 <= stack_bottom + stack_size);
493 542
494 543
495 for (c = (unsigned char*) stack_bottom, i = 544 for (c = (unsigned char*) stack_bottom, i = 0 ;
496 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_ 545 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) && (i < stack_size) ;
497 c++, i++) 546 c++, i++)
498 { 547 {
499 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POI 548 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POISON == *c);
500 } 549 }
501 } 550 }
502 #endif 551 #endif
503 552
504 553
505 554
506 555
507 556
508 557
509 558
510 sos_vaddr_t sos_cpu_context_get_PC(const struc 559 sos_vaddr_t sos_cpu_context_get_PC(const struct sos_cpu_state *ctxt)
511 { 560 {
512 SOS_ASSERT_FATAL(NULL != ctxt); 561 SOS_ASSERT_FATAL(NULL != ctxt);
513 562
514 563
515 564
516 return ctxt->eip; 565 return ctxt->eip;
517 } 566 }
518 567
519 568
520 sos_vaddr_t sos_cpu_context_get_SP(const struc 569 sos_vaddr_t sos_cpu_context_get_SP(const struct sos_cpu_state *ctxt)
521 { 570 {
522 SOS_ASSERT_FATAL(NULL != ctxt); 571 SOS_ASSERT_FATAL(NULL != ctxt);
523 572
524 573
525 574
526 575
527 if (TRUE == sos_cpu_context_is_in_user_mode( 576 if (TRUE == sos_cpu_context_is_in_user_mode(ctxt))
528 { 577 {
529 struct sos_cpu_ustate * uctxt = (struct 578 struct sos_cpu_ustate * uctxt = (struct sos_cpu_ustate*)ctxt;
530 return uctxt->cpl3_esp; 579 return uctxt->cpl3_esp;
531 } 580 }
532 581
533 582
534 583
535 584
536 return (sos_vaddr_t)ctxt; 585 return (sos_vaddr_t)ctxt;
537 } 586 }
538 587
539 588
540 sos_ret_t 589 sos_ret_t
541 sos_cpu_context_set_EX_return_address(struct s 590 sos_cpu_context_set_EX_return_address(struct sos_cpu_state *ctxt,
542 sos_vadd 591 sos_vaddr_t ret_vaddr)
543 { 592 {
544 ctxt->eip = ret_vaddr; 593 ctxt->eip = ret_vaddr;
545 return SOS_OK; 594 return SOS_OK;
546 } 595 }
547 596
548 597
549 void sos_cpu_context_dump(const struct sos_cpu 598 void sos_cpu_context_dump(const struct sos_cpu_state *ctxt)
550 { 599 {
551 char buf[128]; 600 char buf[128];
552 601
553 snprintf(buf, sizeof(buf), 602 snprintf(buf, sizeof(buf),
554 "CPU: eip=%x esp0=%x eflags=%x cs=% 603 "CPU: eip=%x esp0=%x eflags=%x cs=%x ds=%x ss0=%x err=%x",
555 (unsigned)ctxt->eip, (unsigned)ctxt 604 (unsigned)ctxt->eip, (unsigned)ctxt, (unsigned)ctxt->eflags,
556 (unsigned)GET_CPU_CS_REGISTER_VALUE 605 (unsigned)GET_CPU_CS_REGISTER_VALUE(ctxt->cs), (unsigned)ctxt->ds,
557 (unsigned)ctxt->cpl0_ss, 606 (unsigned)ctxt->cpl0_ss,
558 (unsigned)ctxt->error_code); 607 (unsigned)ctxt->error_code);
559 if (TRUE == sos_cpu_context_is_in_user_mode( 608 if (TRUE == sos_cpu_context_is_in_user_mode(ctxt))
560 { 609 {
561 struct sos_cpu_ustate * uctxt = (struct 610 struct sos_cpu_ustate * uctxt = (struct sos_cpu_ustate*)ctxt;
562 snprintf(buf, sizeof(buf), 611 snprintf(buf, sizeof(buf),
563 "%s esp3=%x ss3=%x", 612 "%s esp3=%x ss3=%x",
564 buf, (unsigned)uctxt->cpl3_esp, 613 buf, (unsigned)uctxt->cpl3_esp, (unsigned)uctxt->cpl3_ss);
565 } 614 }
566 else 615 else
567 snprintf(buf, sizeof(buf), "%s [KERNEL MOD 616 snprintf(buf, sizeof(buf), "%s [KERNEL MODE]", buf);
568 617
569 sos_bochs_putstring(buf); sos_bochs_putstrin 618 sos_bochs_putstring(buf); sos_bochs_putstring("\n");
570 sos_x86_videomem_putstring(23, 0, 619 sos_x86_videomem_putstring(23, 0,
571 SOS_X86_VIDEO_FG_ 620 SOS_X86_VIDEO_FG_BLACK | SOS_X86_VIDEO_BG_LTGRAY,
572 buf); 621 buf);
573 } 622 }
574 623
575 624
576 625
577 626
578 627
579 628
580 629
581 sos_ui32_t sos_cpu_context_get_EX_info(const s 630 sos_ui32_t sos_cpu_context_get_EX_info(const struct sos_cpu_state *ctxt)
582 { 631 {
583 SOS_ASSERT_FATAL(NULL != ctxt); 632 SOS_ASSERT_FATAL(NULL != ctxt);
584 return ctxt->error_code; 633 return ctxt->error_code;
585 } 634 }
586 635
587 636
588 sos_vaddr_t 637 sos_vaddr_t
589 sos_cpu_context_get_EX_faulting_vaddr(const st 638 sos_cpu_context_get_EX_faulting_vaddr(const struct sos_cpu_state *ctxt)
590 { 639 {
591 sos_ui32_t cr2; 640 sos_ui32_t cr2;
592 641
593 642
594 643
595 644
596 645
597 646
598 647
599 648
600 649
601 650
602 651
603 652
604 653
605 654
606 asm volatile ("movl %%cr2, %0" 655 asm volatile ("movl %%cr2, %0"
607 :"=r"(cr2) 656 :"=r"(cr2)
608 : ); 657 : );
609 658
610 return cr2; 659 return cr2;
611 } 660 }
612 661
613 662
614 663
615 664
616 665
617 666
618 667
619 668
620 669
621 670
622 671
623 672
624 673
625 674
626 675
627 676
628 677
629 inline 678 inline
630 sos_ret_t sos_syscall_get3args(const struct so 679 sos_ret_t sos_syscall_get3args(const struct sos_cpu_state *user_ctxt,
631 unsign 680 unsigned int *arg1,
632 unsign 681 unsigned int *arg2,
633 unsign 682 unsigned int *arg3)
634 { 683 {
635 *arg1 = user_ctxt->ebx; 684 *arg1 = user_ctxt->ebx;
636 *arg2 = user_ctxt->ecx; 685 *arg2 = user_ctxt->ecx;
637 *arg3 = user_ctxt->edx; 686 *arg3 = user_ctxt->edx;
638 return SOS_OK; 687 return SOS_OK;
639 } 688 }
640 689
641 690
642 sos_ret_t sos_syscall_get1arg(const struct sos 691 sos_ret_t sos_syscall_get1arg(const struct sos_cpu_state *user_ctxt,
643 unsigne 692 unsigned int *arg1)
644 { 693 {
645 unsigned int unused; 694 unsigned int unused;
646 return sos_syscall_get3args(user_ctxt, arg1, 695 return sos_syscall_get3args(user_ctxt, arg1, & unused, & unused);
647 } 696 }
648 697
649 698
650 sos_ret_t sos_syscall_get2args(const struct so 699 sos_ret_t sos_syscall_get2args(const struct sos_cpu_state *user_ctxt,
651 unsign 700 unsigned int *arg1,
652 unsign 701 unsigned int *arg2)
653 { 702 {
654 unsigned int unused; 703 unsigned int unused;
655 return sos_syscall_get3args(user_ctxt, arg1, 704 return sos_syscall_get3args(user_ctxt, arg1, arg2, & unused);
656 } 705 }
657 706
658 707
659 708
660 709
661 710
662 711
663 712
664 sos_ret_t sos_syscall_get4args(const struct so 713 sos_ret_t sos_syscall_get4args(const struct sos_cpu_state *user_ctxt,
665 unsign 714 unsigned int *arg1,
666 unsign 715 unsigned int *arg2,
667 unsign 716 unsigned int *arg3,
668 unsign 717 unsigned int *arg4)
669 { 718 {
670 sos_uaddr_t uaddr_other_args; 719 sos_uaddr_t uaddr_other_args;
671 unsigned int other_args[2]; 720 unsigned int other_args[2];
672 sos_ret_t retval; 721 sos_ret_t retval;
673 722
674 723
675 724
676 retval = sos_syscall_get3args(user_ctxt, arg 725 retval = sos_syscall_get3args(user_ctxt, arg1, arg2,
677 (unsigned int 726 (unsigned int *)& uaddr_other_args);
678 if (SOS_OK != retval) 727 if (SOS_OK != retval)
679 return retval; 728 return retval;
680 729
681 730
682 731
683 retval = sos_memcpy_from_user((sos_vaddr_t)o 732 retval = sos_memcpy_from_user((sos_vaddr_t)other_args,
684 (sos_uaddr_t)u 733 (sos_uaddr_t)uaddr_other_args,
685 sizeof(other_a 734 sizeof(other_args));
686 if (sizeof(other_args) != retval) 735 if (sizeof(other_args) != retval)
687 return -SOS_EFAULT; 736 return -SOS_EFAULT;
688 737
689 *arg3 = other_args[0]; 738 *arg3 = other_args[0];
690 *arg4 = other_args[1]; 739 *arg4 = other_args[1];
691 return SOS_OK; 740 return SOS_OK;
692 } 741 }
693 742
694 743
695 sos_ret_t sos_syscall_get5args(const struct so 744 sos_ret_t sos_syscall_get5args(const struct sos_cpu_state *user_ctxt,
696 unsign 745 unsigned int *arg1,
697 unsign 746 unsigned int *arg2,
698 unsign 747 unsigned int *arg3,
699 unsign 748 unsigned int *arg4,
700 unsign 749 unsigned int *arg5)
701 { 750 {
702 sos_uaddr_t uaddr_other_args; 751 sos_uaddr_t uaddr_other_args;
703 unsigned int other_args[3]; 752 unsigned int other_args[3];
704 sos_ret_t retval; 753 sos_ret_t retval;
705 754
706 755
707 756
708 retval = sos_syscall_get3args(user_ctxt, arg 757 retval = sos_syscall_get3args(user_ctxt, arg1, arg2,
709 (unsigned int 758 (unsigned int *)& uaddr_other_args);
710 if (SOS_OK != retval) 759 if (SOS_OK != retval)
711 return retval; 760 return retval;
712 761
713 762
714 763
715 retval = sos_memcpy_from_user((sos_vaddr_t)o 764 retval = sos_memcpy_from_user((sos_vaddr_t)other_args,
716 (sos_uaddr_t)u 765 (sos_uaddr_t)uaddr_other_args,
717 sizeof(other_a 766 sizeof(other_args));
718 if (sizeof(other_args) != retval) 767 if (sizeof(other_args) != retval)
719 return -SOS_EFAULT; 768 return -SOS_EFAULT;
720 769
721 *arg3 = other_args[0]; 770 *arg3 = other_args[0];
722 *arg4 = other_args[1]; 771 *arg4 = other_args[1];
723 *arg5 = other_args[2]; 772 *arg5 = other_args[2];
724 return SOS_OK; 773 return SOS_OK;
725 } 774 }
726 775
727 776
728 sos_ret_t sos_syscall_get6args(const struct so 777 sos_ret_t sos_syscall_get6args(const struct sos_cpu_state *user_ctxt,
729 unsign 778 unsigned int *arg1,
730 unsign 779 unsigned int *arg2,
731 unsign 780 unsigned int *arg3,
732 unsign 781 unsigned int *arg4,
733 unsign 782 unsigned int *arg5,
734 unsign 783 unsigned int *arg6)
735 { 784 {
736 sos_uaddr_t uaddr_other_args; 785 sos_uaddr_t uaddr_other_args;
737 unsigned int other_args[4]; 786 unsigned int other_args[4];
738 sos_ret_t retval; 787 sos_ret_t retval;
739 788
740 789
741 790
742 retval = sos_syscall_get3args(user_ctxt, arg 791 retval = sos_syscall_get3args(user_ctxt, arg1, arg2,
743 (unsigned int 792 (unsigned int *)& uaddr_other_args);
744 if (SOS_OK != retval) 793 if (SOS_OK != retval)
745 return retval; 794 return retval;
746 795
747 796
748 797
749 retval = sos_memcpy_from_user((sos_vaddr_t)o 798 retval = sos_memcpy_from_user((sos_vaddr_t)other_args,
750 (sos_uaddr_t)u 799 (sos_uaddr_t)uaddr_other_args,
751 sizeof(other_a 800 sizeof(other_args));
752 if (sizeof(other_args) != retval) 801 if (sizeof(other_args) != retval)
753 return -SOS_EFAULT; 802 return -SOS_EFAULT;
754 803
755 *arg3 = other_args[0]; 804 *arg3 = other_args[0];
756 *arg4 = other_args[1]; 805 *arg4 = other_args[1];
757 *arg5 = other_args[2]; 806 *arg5 = other_args[2];
758 *arg6 = other_args[3]; 807 *arg6 = other_args[3];
759 return SOS_OK; 808 return SOS_OK;
760 } 809 }
761 810
762 811
763 sos_ret_t sos_syscall_get7args(const struct so 812 sos_ret_t sos_syscall_get7args(const struct sos_cpu_state *user_ctxt,
764 unsign 813 unsigned int *arg1,
765 unsign 814 unsigned int *arg2,
766 unsign 815 unsigned int *arg3,
767 unsign 816 unsigned int *arg4,
768 unsign 817 unsigned int *arg5,
769 unsign 818 unsigned int *arg6,
770 unsign 819 unsigned int *arg7)
771 { 820 {
772 sos_uaddr_t uaddr_other_args; 821 sos_uaddr_t uaddr_other_args;
773 unsigned int other_args[5]; 822 unsigned int other_args[5];
774 sos_ret_t retval; 823 sos_ret_t retval;
775 824
776 825
777 826
778 retval = sos_syscall_get3args(user_ctxt, arg 827 retval = sos_syscall_get3args(user_ctxt, arg1, arg2,
779 (unsigned int 828 (unsigned int *)& uaddr_other_args);
780 if (SOS_OK != retval) 829 if (SOS_OK != retval)
781 return retval; 830 return retval;
782 831
783 832
784 833
785 retval = sos_memcpy_from_user((sos_vaddr_t)o 834 retval = sos_memcpy_from_user((sos_vaddr_t)other_args,
786 (sos_uaddr_t)u 835 (sos_uaddr_t)uaddr_other_args,
787 sizeof(other_a 836 sizeof(other_args));
788 if (sizeof(other_args) != retval) 837 if (sizeof(other_args) != retval)
789 return -SOS_EFAULT; 838 return -SOS_EFAULT;
790 839
791 *arg3 = other_args[0]; 840 *arg3 = other_args[0];
792 *arg4 = other_args[1]; 841 *arg4 = other_args[1];
793 *arg5 = other_args[2]; 842 *arg5 = other_args[2];
794 *arg6 = other_args[3]; 843 *arg6 = other_args[3];
795 *arg7 = other_args[4]; 844 *arg7 = other_args[4];
796 return SOS_OK; 845 return SOS_OK;
797 } 846 }
798 847
799 848
800 sos_ret_t sos_syscall_get8args(const struct so 849 sos_ret_t sos_syscall_get8args(const struct sos_cpu_state *user_ctxt,
801 unsign 850 unsigned int *arg1,
802 unsign 851 unsigned int *arg2,
803 unsign 852 unsigned int *arg3,
804 unsign 853 unsigned int *arg4,
805 unsign 854 unsigned int *arg5,
806 unsign 855 unsigned int *arg6,
807 unsign 856 unsigned int *arg7,
808 unsign 857 unsigned int *arg8)
809 { 858 {
810 sos_uaddr_t uaddr_other_args; 859 sos_uaddr_t uaddr_other_args;
811 unsigned int other_args[6]; 860 unsigned int other_args[6];
812 sos_ret_t retval; 861 sos_ret_t retval;
813 862
814 863
815 864
816 retval = sos_syscall_get3args(user_ctxt, arg 865 retval = sos_syscall_get3args(user_ctxt, arg1, arg2,
817 (unsigned int 866 (unsigned int *)& uaddr_other_args);
818 if (SOS_OK != retval) 867 if (SOS_OK != retval)
819 return retval; 868 return retval;
820 869
821 870
822 871
823 retval = sos_memcpy_from_user((sos_vaddr_t)o 872 retval = sos_memcpy_from_user((sos_vaddr_t)other_args,
824 (sos_uaddr_t)u 873 (sos_uaddr_t)uaddr_other_args,
825 sizeof(other_a 874 sizeof(other_args));
826 if (sizeof(other_args) != retval) 875 if (sizeof(other_args) != retval)
827 return -SOS_EFAULT; 876 return -SOS_EFAULT;
828 877
829 *arg3 = other_args[0]; 878 *arg3 = other_args[0];
830 *arg4 = other_args[1]; 879 *arg4 = other_args[1];
831 *arg5 = other_args[2]; 880 *arg5 = other_args[2];
832 *arg6 = other_args[3]; 881 *arg6 = other_args[3];
833 *arg7 = other_args[4]; 882 *arg7 = other_args[4];
834 *arg8 = other_args[5]; 883 *arg8 = other_args[5];
835 return SOS_OK; 884 return SOS_OK;
836 } 885 }
837 886
838 887
839 888
840 889
841 890
842 891
843 892
844 sos_ui32_t sos_backtrace(const struct sos_cpu_ 893 sos_ui32_t sos_backtrace(const struct sos_cpu_state *cpu_state,
845 sos_ui32_t max_depth, 894 sos_ui32_t max_depth,
846 sos_vaddr_t stack_bot 895 sos_vaddr_t stack_bottom,
847 sos_size_t stack_size 896 sos_size_t stack_size,
848 sos_backtrace_callbac 897 sos_backtrace_callback_t * backtracer,
849 void *custom_arg) 898 void *custom_arg)
850 { 899 {
851 int depth; 900 int depth;
852 sos_vaddr_t callee_PC, caller_frame; 901 sos_vaddr_t callee_PC, caller_frame;
853 902
854 903
855 if ((NULL != cpu_state) 904 if ((NULL != cpu_state)
856 && 905 &&
857 (TRUE == sos_cpu_context_is_in_user_mode 906 (TRUE == sos_cpu_context_is_in_user_mode(cpu_state)))
858 { 907 {
859 return 0; 908 return 0;
860 } 909 }
861 910
862 911
863 912
864 913
865 914
866 915
867 916
868 917
869 918
870 919
871 920
872 921
873 922
874 923
875 924
876 925
877 926
878 927
879 928
880 929
881 930
882 931
883 932
884 933
885 934
886 935
887 936
888 937
889 938
890 939
891 if (cpu_state) 940 if (cpu_state)
892 { 941 {
893 callee_PC = cpu_state->eip; 942 callee_PC = cpu_state->eip;
894 caller_frame = cpu_state->ebp; 943 caller_frame = cpu_state->ebp;
895 } 944 }
896 else 945 else
897 { 946 {
898 947
899 callee_PC = (sos_vaddr_t)__builtin_re 948 callee_PC = (sos_vaddr_t)__builtin_return_address(0);
900 caller_frame = (sos_vaddr_t)__builtin_fr 949 caller_frame = (sos_vaddr_t)__builtin_frame_address(1);
901 } 950 }
902 951
903 for(depth=0 ; depth < max_depth ; depth ++) 952 for(depth=0 ; depth < max_depth ; depth ++)
904 { 953 {
905 954
906 backtracer(callee_PC, caller_frame + 8, 955 backtracer(callee_PC, caller_frame + 8, depth, custom_arg);
907 956
908 957
909 if ( (caller_frame < stack_bottom) 958 if ( (caller_frame < stack_bottom)
910 || (caller_frame + 4 >= stack_botto 959 || (caller_frame + 4 >= stack_bottom + stack_size) )
911 return depth; 960 return depth;
912 961
913 962
914 callee_PC = *((sos_vaddr_t*) (caller_ 963 callee_PC = *((sos_vaddr_t*) (caller_frame + 4));
915 caller_frame = *((sos_vaddr_t*) caller_f 964 caller_frame = *((sos_vaddr_t*) caller_frame);
916 } 965 }
917 966
918 return depth; 967 return depth;
919 } 968 }
920 969
921 970
922 971
923 972
924 973
925 974
926 975
927 976
928 977
929 978
930 979
931 void 980 void
932 sos_cpu_context_update_kernel_tss(struct sos_c 981 sos_cpu_context_update_kernel_tss(struct sos_cpu_state *next_ctxt)
933 { 982 {
934 983
935 if (sos_cpu_context_is_in_user_mode(next_ctx 984 if (sos_cpu_context_is_in_user_mode(next_ctxt))
936 { 985 {
937 986
938 987
939 988
940 989
941 990
942 991
943 992
944 993
945 994
946 995
947 996
948 kernel_tss.esp0 = ((sos_vaddr_t)next_ctx 997 kernel_tss.esp0 = ((sos_vaddr_t)next_ctxt)
949 + sizeof(struct sos_cp 998 + sizeof(struct sos_cpu_ustate);
950 999
951 1000
952 1001
953 } 1002 }
954 else 1003 else
955 { 1004 {
956 1005
957 1006
958 } 1007 }
959 } 1008 }