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 #include <bootstrap/multiboot.h> 021 #include <bootstrap/multiboot.h>
021 #include <hwcore/idt.h> 022 #include <hwcore/idt.h>
022 #include <hwcore/gdt.h> 023 #include <hwcore/gdt.h>
023 #include <hwcore/irq.h> 024 #include <hwcore/irq.h>
024 #include <hwcore/exception.h> 025 #include <hwcore/exception.h>
025 #include <hwcore/i8254.h> 026 #include <hwcore/i8254.h>
026 #include <sos/list.h> 027 #include <sos/list.h>
027 #include <sos/physmem.h> 028 #include <sos/physmem.h>
028 #include <hwcore/paging.h> 029 #include <hwcore/paging.h>
029 #include <sos/kmem_vmm.h> 030 #include <sos/kmem_vmm.h>
030 #include <sos/kmalloc.h> 031 #include <sos/kmalloc.h>
031 #include <sos/time.h> <<
032 #include <sos/thread.h> <<
033 #include <sos/klibc.h> 032 #include <sos/klibc.h>
034 #include <sos/assert.h> 033 #include <sos/assert.h>
035 #include <drivers/x86_videomem.h> 034 #include <drivers/x86_videomem.h>
036 #include <drivers/bochs.h> 035 #include <drivers/bochs.h>
037 036
038 037
039 038
040 039
041 void display_bits(unsigned char row, unsigned 040 void display_bits(unsigned char row, unsigned char col,
042 unsigned char attribute, 041 unsigned char attribute,
043 sos_ui32_t integer) 042 sos_ui32_t integer)
044 { 043 {
045 int i; 044 int i;
046 045
047 for (i = 31 ; i >= 0 ; i--) 046 for (i = 31 ; i >= 0 ; i--)
048 { 047 {
049 048
050 int bit_i = (integer & (1 << i)); 049 int bit_i = (integer & (1 << i));
051 050
052 unsigned char ascii_code = bit_i?219:177 051 unsigned char ascii_code = bit_i?219:177;
053 sos_x86_videomem_putchar(row, col++, 052 sos_x86_videomem_putchar(row, col++,
054 attribute, 053 attribute,
055 ascii_code); 054 ascii_code);
056 } 055 }
057 } 056 }
058 057
059 058
060 059
061 static void clk_it(int intid) !! 060 static void clk_it(int intid,
>> 061 const struct sos_cpu_kstate *cpu_kstate)
062 { 062 {
063 static sos_ui32_t clock_count = 0; 063 static sos_ui32_t clock_count = 0;
064 064
065 display_bits(0, 48, 065 display_bits(0, 48,
066 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 066 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
067 clock_count); 067 clock_count);
068 clock_count++; 068 clock_count++;
069 <<
070 <<
071 sos_time_do_tick(); <<
072 } 069 }
073 070
074 071
075 072
076 073
077 074
078 075
079 076
080 static void dump_backtrace(const struct sos_cp !! 077 static void dump_backtrace(const struct sos_cpu_kstate *cpu_kstate,
081 sos_vaddr_t stack_b 078 sos_vaddr_t stack_bottom,
082 sos_size_t stack_s 079 sos_size_t stack_size,
083 sos_bool_t on_conso 080 sos_bool_t on_console,
084 sos_bool_t on_bochs 081 sos_bool_t on_bochs)
085 { 082 {
086 static void backtracer(sos_vaddr_t PC, 083 static void backtracer(sos_vaddr_t PC,
087 sos_vaddr_t params, 084 sos_vaddr_t params,
088 sos_ui32_t depth, 085 sos_ui32_t depth,
089 void *custom_arg) 086 void *custom_arg)
090 { 087 {
091 sos_ui32_t invalid = 0xffffffff, *arg1, 088 sos_ui32_t invalid = 0xffffffff, *arg1, *arg2, *arg3, *arg4;
092 089
093 090
094 091
095 092
096 093
097 arg1 = (sos_ui32_t*)params; 094 arg1 = (sos_ui32_t*)params;
098 arg2 = (sos_ui32_t*)(params+4); 095 arg2 = (sos_ui32_t*)(params+4);
099 arg3 = (sos_ui32_t*)(params+8); 096 arg3 = (sos_ui32_t*)(params+8);
100 arg4 = (sos_ui32_t*)(params+12); 097 arg4 = (sos_ui32_t*)(params+12);
101 098
102 099
103 100
104 #define INTERVAL_OK(b,v,u) ( ((b) <= (sos_vadd 101 #define INTERVAL_OK(b,v,u) ( ((b) <= (sos_vaddr_t)(v)) \
105 && ((sos_vaddr_t) 102 && ((sos_vaddr_t)(v) < (u)) )
106 if (!INTERVAL_OK(stack_bottom, arg1, sta 103 if (!INTERVAL_OK(stack_bottom, arg1, stack_bottom + stack_size))
107 arg1 = &invalid; 104 arg1 = &invalid;
108 if (!INTERVAL_OK(stack_bottom, arg2, sta 105 if (!INTERVAL_OK(stack_bottom, arg2, stack_bottom + stack_size))
109 arg2 = &invalid; 106 arg2 = &invalid;
110 if (!INTERVAL_OK(stack_bottom, arg3, sta 107 if (!INTERVAL_OK(stack_bottom, arg3, stack_bottom + stack_size))
111 arg3 = &invalid; 108 arg3 = &invalid;
112 if (!INTERVAL_OK(stack_bottom, arg4, sta 109 if (!INTERVAL_OK(stack_bottom, arg4, stack_bottom + stack_size))
113 arg4 = &invalid; 110 arg4 = &invalid;
114 111
115 112
116 if (on_bochs) 113 if (on_bochs)
117 sos_bochs_printf("[%d] PC=0x%x arg1=0x 114 sos_bochs_printf("[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x\n",
118 (unsigned)depth, (uns 115 (unsigned)depth, (unsigned)PC,
119 (unsigned)*arg1, (uns 116 (unsigned)*arg1, (unsigned)*arg2,
120 (unsigned)*arg3); 117 (unsigned)*arg3);
121 118
122 if (on_console) 119 if (on_console)
123 sos_x86_videomem_printf(23-depth, 3, 120 sos_x86_videomem_printf(23-depth, 3,
124 SOS_X86_VIDEO_ 121 SOS_X86_VIDEO_BG_BLUE
125 | SOS_X86_VI 122 | SOS_X86_VIDEO_FG_LTGREEN,
126 "[%d] PC=0x%x 123 "[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x arg4=0x%x",
127 (unsigned)dept 124 (unsigned)depth, PC,
128 (unsigned)*arg 125 (unsigned)*arg1, (unsigned)*arg2,
129 (unsigned)*arg 126 (unsigned)*arg3, (unsigned)*arg4);
130 127
131 } 128 }
132 129
133 sos_backtrace(cpu_state, 15, stack_bottom, s !! 130 sos_backtrace(cpu_kstate, 15, stack_bottom, stack_size, backtracer, NULL);
134 } 131 }
135 132
136 133
137 134
138 static void pgflt_ex(int intid, const struct s !! 135 static void pgflt_ex(int intid, const struct sos_cpu_kstate *ctxt)
139 { 136 {
140 static sos_ui32_t demand_paging_count = 0; 137 static sos_ui32_t demand_paging_count = 0;
141 sos_vaddr_t faulting_vaddr = sos_cpu_context !! 138 sos_vaddr_t faulting_vaddr = sos_cpu_kstate_get_EX_faulting_vaddr(ctxt);
142 sos_paddr_t ppage_paddr; 139 sos_paddr_t ppage_paddr;
143 140
144 141
145 if (! sos_kmem_vmm_is_valid_vaddr(faulting_v 142 if (! sos_kmem_vmm_is_valid_vaddr(faulting_vaddr))
146 { 143 {
147 144
148 145
149 dump_backtrace(ctxt, 146 dump_backtrace(ctxt,
150 bootstrap_stack_bottom, 147 bootstrap_stack_bottom,
151 bootstrap_stack_size, 148 bootstrap_stack_size,
152 TRUE, TRUE); 149 TRUE, TRUE);
153 sos_display_fatal_error("Unresolved page !! 150 sos_display_fatal_error("Unresolved page Fault on access to address 0x%x (info=%x)!",
154 sos_cpu_context_ <<
155 (unsigned)faulti 151 (unsigned)faulting_vaddr,
156 (unsigned)sos_cp !! 152 (unsigned)sos_cpu_kstate_get_EX_info(ctxt));
157 SOS_ASSERT_FATAL(! "Got page fault (note 153 SOS_ASSERT_FATAL(! "Got page fault (note: demand paging is disabled)");
158 } 154 }
159 155
160 156
161 157
162 158
163 159
164 160
165 161
166 demand_paging_count ++; 162 demand_paging_count ++;
167 display_bits(0, 0, 163 display_bits(0, 0,
168 SOS_X86_VIDEO_FG_LTRED | SOS_X8 164 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
169 demand_paging_count); 165 demand_paging_count);
170 166
171 167
172 ppage_paddr = sos_physmem_ref_physpage_new(F 168 ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
173 if (! ppage_paddr) 169 if (! ppage_paddr)
174 SOS_ASSERT_FATAL(! "TODO: implement swap. 170 SOS_ASSERT_FATAL(! "TODO: implement swap. (Out of mem in demand paging because no swap for kernel yet !)");
175 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(pp 171 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(ppage_paddr,
176 SO 172 SOS_PAGE_ALIGN_INF(faulting_vaddr),
177 FA 173 FALSE,
178 SO 174 SOS_VM_MAP_PROT_READ
179 | 175 | SOS_VM_MAP_PROT_WRITE
180 | 176 | SOS_VM_MAP_ATOMIC));
181 sos_physmem_unref_physpage(ppage_paddr); 177 sos_physmem_unref_physpage(ppage_paddr);
182 178
183 179
184 } 180 }
185 181
186 182
>> 183
187 184
188 !! 185
189 !! 186
190 !! 187
191 !! 188
>> 189
>> 190
192 191
>> 192 struct sos_cpu_kstate *ctxt_hello1;
>> 193 struct sos_cpu_kstate *ctxt_hello2;
>> 194 struct sos_cpu_kstate *ctxt_main;
>> 195 sos_vaddr_t hello1_stack, hello2_stack;
193 196
194 struct thr_arg !! 197 static void reclaim_stack(sos_vaddr_t stack_vaddr)
195 { 198 {
196 char character; !! 199 sos_kfree(stack_vaddr);
197 int color; !! 200 }
198 201
199 int col; !! 202
200 int row; !! 203 static void exit_hello12(sos_vaddr_t stack_vaddr)
201 }; !! 204 {
>> 205 sos_cpu_kstate_exit_to(ctxt_main,
>> 206 (sos_cpu_kstate_function_arg1_t*) reclaim_stack,
>> 207 stack_vaddr);
>> 208 }
>> 209
>> 210
>> 211 static void hello1 (char *str)
>> 212 {
>> 213 for ( ; *str != '\n' ; str++)
>> 214 {
>> 215 sos_bochs_printf("hello1: %c\n", *str);
>> 216 sos_cpu_kstate_switch(& ctxt_hello1, ctxt_hello2);
>> 217 }
>> 218
>> 219
>> 220
>> 221
>> 222
>> 223
>> 224 }
>> 225
>> 226
>> 227 static void hello2 (char *str)
>> 228 {
>> 229 for ( ; *str != '\n' ; str++)
>> 230 {
>> 231 sos_bochs_printf("hello2: %c\n", *str);
>> 232 sos_cpu_kstate_switch(& ctxt_hello2, ctxt_hello1);
>> 233 }
>> 234
>> 235
>> 236
>> 237
>> 238
>> 239
>> 240 }
>> 241
>> 242
>> 243 void print_hello_world ()
>> 244 {
>> 245 #define DEMO_STACK_SIZE 1024
>> 246
>> 247 hello1_stack = sos_kmalloc(DEMO_STACK_SIZE, 0);
>> 248 hello2_stack = sos_kmalloc(DEMO_STACK_SIZE, 0);
>> 249
>> 250
>> 251 sos_cpu_kstate_init(&ctxt_hello1,
>> 252 (sos_cpu_kstate_function_arg1_t*) hello1,
>> 253 (sos_ui32_t) "Hlowrd",
>> 254 (sos_vaddr_t) hello1_stack, DEMO_STACK_SIZE,
>> 255 (sos_cpu_kstate_function_arg1_t*) exit_hello12,
>> 256 (sos_ui32_t) hello1_stack);
>> 257 sos_cpu_kstate_init(&ctxt_hello2,
>> 258 (sos_cpu_kstate_function_arg1_t*) hello2,
>> 259 (sos_ui32_t) "el ol\n",
>> 260 (sos_vaddr_t) hello2_stack, DEMO_STACK_SIZE,
>> 261 (sos_cpu_kstate_function_arg1_t*) exit_hello12,
>> 262 (sos_ui32_t) hello2_stack);
>> 263
>> 264
>> 265 sos_bochs_printf("Printing Hello World\\n...\n");
>> 266 sos_cpu_kstate_switch(& ctxt_main, ctxt_hello1);
>> 267
>> 268
>> 269 sos_bochs_printf("Back in main !\n");
>> 270 }
>> 271
>> 272
>> 273
>> 274
>> 275
>> 276
>> 277
>> 278 static void test_demand_paging(int nb_alloc_vpages, int nb_alloc_ppages)
>> 279 {
>> 280 int i;
>> 281 sos_vaddr_t base_vaddr;
>> 282
>> 283 sos_x86_videomem_printf(10, 0,
>> 284 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_LTGREEN,
>> 285 "Demand paging test (alloc %dMB of VMM, test %dkB RAM)",
>> 286 nb_alloc_vpages >> 8, nb_alloc_ppages << 2);
>> 287
>> 288
>> 289 base_vaddr = sos_kmem_vmm_alloc(nb_alloc_vpages, 0);
>> 290
>> 291 SOS_ASSERT_FATAL(base_vaddr != (sos_vaddr_t)NULL);
>> 292 sos_x86_videomem_printf(11, 0,
>> 293 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 294 "Allocated virtual region [0x%x, 0x%x[",
>> 295 base_vaddr,
>> 296 base_vaddr + nb_alloc_vpages*SOS_PAGE_SIZE);
>> 297
>> 298
>> 299 for (i = 0 ; (i < nb_alloc_ppages) && (i < nb_alloc_vpages) ; i++)
>> 300 {
>> 301
>> 302 sos_ui32_t *value, j;
>> 303 sos_vaddr_t vaddr = base_vaddr;
>> 304 vaddr += (nb_alloc_vpages - (i + 1))*SOS_PAGE_SIZE;
>> 305 vaddr += 2345;
>> 306
>> 307 sos_x86_videomem_printf(12, 0,
>> 308 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 309 "Writing %d at virtual address 0x%x...",
>> 310 i, vaddr);
>> 311
>> 312
>> 313 value = (sos_ui32_t*)vaddr;
>> 314 *value = i;
>> 315
>> 316
>> 317 sos_x86_videomem_printf(13, 0,
>> 318 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 319 "Value read at address 0x%x = %d",
>> 320 vaddr, (unsigned)*value);
>> 321 }
>> 322
>> 323 SOS_ASSERT_FATAL(SOS_OK == sos_kmem_vmm_free(base_vaddr));
>> 324
>> 325 sos_x86_videomem_printf(14, 0,
>> 326 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 327 "Done (area un-allocated)");
>> 328 }
>> 329
>> 330
>> 331
>> 332
>> 333
>> 334
>> 335
>> 336
>> 337 static void test_backtrace(int i, int magic, sos_vaddr_t stack_bottom,
>> 338 sos_size_t stack_size)
>> 339 {
>> 340 if (i <= 0)
>> 341 {
>> 342
>> 343
>> 344 *((char*)0x42) = 12;
>> 345
>> 346
>> 347
>> 348 }
>> 349 else
>> 350 test_backtrace(i-1, magic, stack_bottom, stack_size);
>> 351 }
>> 352
>> 353
>> 354
>> 355
>> 356
>> 357
>> 358
>> 359
>> 360
>> 361
>> 362
>> 363
>> 364
>> 365
>> 366
>> 367
>> 368
>> 369
>> 370
>> 371
>> 372
>> 373
>> 374
>> 375
>> 376
>> 377
>> 378
>> 379
>> 380
>> 381
>> 382
>> 383
>> 384
>> 385
>> 386
>> 387
>> 388
>> 389
>> 390
>> 391
>> 392
>> 393
>> 394
>> 395
>> 396
>> 397
>> 398
>> 399
>> 400
>> 401
>> 402
>> 403
>> 404
>> 405
>> 406
>> 407
>> 408
>> 409
>> 410
>> 411
>> 412
>> 413
>> 414
>> 415
>> 416
>> 417
>> 418
>> 419
>> 420
>> 421
>> 422
>> 423
>> 424
>> 425
>> 426
>> 427
>> 428
>> 429
>> 430
>> 431
202 432
203 433
204 static void demo_thread(void *arg) !! 434
>> 435 static char stack_reader[1024];
>> 436 static char stack_lexer[1024];
>> 437 static char deep_stack[65536];
>> 438
>> 439
>> 440 static struct sos_cpu_kstate *st_reader, *st_lexer, *st_parser,
>> 441 *st_eval, *st_free, *st_main;
>> 442
>> 443
>> 444
>> 445
>> 446
>> 447
>> 448 static void reclaim(int unused)
205 { 449 {
206 struct thr_arg *thr_arg = (struct thr_arg*)a !! 450 }
207 int progress = 0; !! 451 static void func_exit(sos_ui32_t unused)
>> 452 {
>> 453 sos_cpu_kstate_exit_to(st_main, (sos_cpu_kstate_function_arg1_t*)reclaim, 0);
>> 454 }
208 455
209 sos_bochs_printf("start %c", thr_arg->charac !! 456
210 while (1) !! 457
>> 458
>> 459
>> 460
>> 461
>> 462 static char data_reader_to_lexer;
>> 463
>> 464 static void func_reader(const char *str)
>> 465 {
>> 466 for ( ; str && (*str != '\0') ; str++)
211 { 467 {
212 progress ++; !! 468 data_reader_to_lexer = *str;
213 display_bits(thr_arg->row, thr_arg->col+ !! 469 sos_cpu_kstate_switch(& st_reader, st_lexer);
>> 470 }
>> 471
>> 472 data_reader_to_lexer = '\0';
>> 473 sos_cpu_kstate_switch(& st_reader, st_lexer);
>> 474 }
>> 475
214 476
215 sos_bochs_putchar(thr_arg->character); !! 477
>> 478
>> 479
>> 480
>> 481
>> 482
>> 483 #define STR_VAR_MAXLEN 16
>> 484 static struct lex_elem
>> 485 {
>> 486 enum { LEX_IS_NUMBER, LEX_IS_OPER, LEX_IS_VAR,
>> 487 LEX_IS_OPENPAR, LEX_IS_CLOSEPAR, LEX_END } type;
>> 488 union {
>> 489 int number;
>> 490 char operator;
>> 491 char var[STR_VAR_MAXLEN];
>> 492 };
>> 493 } data_lexer_to_parser;
216 494
217 !! 495 static void func_lexer(sos_ui32_t unused)
218 if ((random() % 100) == 0) !! 496 {
>> 497 char c;
>> 498 enum { GOT_SPACE, GOT_NUM, GOT_OP, GOT_STR,
>> 499 GOT_OPENPAR, GOT_CLOSEPAR } got_what, got_what_before;
>> 500
>> 501 data_lexer_to_parser.number = 0;
>> 502 got_what_before = GOT_SPACE;
>> 503 do
>> 504 {
>> 505
>> 506 sos_cpu_kstate_switch(& st_lexer, st_reader);
>> 507 c = data_reader_to_lexer;
>> 508
>> 509
>> 510 if ( (c >= '0') && (c <= '9') )
>> 511 got_what = GOT_NUM;
>> 512 else if ( (c == '+') || (c == '-') || (c == '*') || (c == '/') )
>> 513 got_what = GOT_OP;
>> 514 else if ( ( (c >= 'a') && (c <= 'z') )
>> 515 || ( (c >= 'A') && (c <= 'Z') ) )
>> 516 got_what = GOT_STR;
>> 517 else if (c == '(')
>> 518 got_what = GOT_OPENPAR;
>> 519 else if (c == ')')
>> 520 got_what = GOT_CLOSEPAR;
>> 521 else
>> 522 got_what = GOT_SPACE;
>> 523
>> 524
>> 525 if ( (got_what != got_what_before)
>> 526 || (got_what_before == GOT_OP)
>> 527 || (got_what_before == GOT_OPENPAR)
>> 528 || (got_what_before == GOT_CLOSEPAR) )
219 { 529 {
220 sos_bochs_printf("[37myield(%c)[m\ !! 530
221 sos_x86_videomem_putchar(thr_arg->ro !! 531
222 SOS_ASSERT_FATAL(SOS_OK == sos_threa !! 532 if ( (got_what_before != GOT_SPACE) )
223 sos_x86_videomem_putchar(thr_arg->ro !! 533 sos_cpu_kstate_switch(& st_lexer, st_parser);
>> 534
>> 535 data_lexer_to_parser.number = 0;
224 } 536 }
225 537
226 !! 538
227 else if ((random() % 200) == 0) !! 539 if (got_what == GOT_OP)
228 { 540 {
229 struct sos_time t = (struct sos_time !! 541 data_lexer_to_parser.type = LEX_IS_OPER;
230 sos_bochs_printf("[37msleep1(%c)[m !! 542 data_lexer_to_parser.operator = c;
231 sos_x86_videomem_putchar(thr_arg->ro <<
232 SOS_ASSERT_FATAL(SOS_OK == sos_threa <<
233 SOS_ASSERT_FATAL(sos_time_is_zero(& <<
234 sos_x86_videomem_putchar(thr_arg->ro <<
235 } 543 }
236 !! 544 else if (got_what == GOT_NUM)
237 !! 545 {
238 else if ((random() % 300) == 0) !! 546 data_lexer_to_parser.type = LEX_IS_NUMBER;
>> 547 data_lexer_to_parser.number *= 10;
>> 548 data_lexer_to_parser.number += (c - '0');
>> 549 }
>> 550 else if (got_what == GOT_STR)
239 { 551 {
240 struct sos_time t = (struct sos_time !! 552 char to_cat[] = { c, '\0' };
241 sos_bochs_printf("[37msleep2(%c)[m !! 553 data_lexer_to_parser.type = LEX_IS_VAR;
242 sos_x86_videomem_putchar(thr_arg->ro !! 554 strzcat(data_lexer_to_parser.var, to_cat, STR_VAR_MAXLEN);
243 SOS_ASSERT_FATAL(SOS_OK == sos_threa <<
244 SOS_ASSERT_FATAL(sos_time_is_zero(& <<
245 sos_x86_videomem_putchar(thr_arg->ro <<
246 } 555 }
>> 556 else if (got_what == GOT_OPENPAR)
>> 557 data_lexer_to_parser.type = LEX_IS_OPENPAR;
>> 558 else if (got_what == GOT_CLOSEPAR)
>> 559 data_lexer_to_parser.type = LEX_IS_CLOSEPAR;
247 560
248 !! 561 got_what_before = got_what;
249 } 562 }
>> 563 while (c != '\0');
>> 564
>> 565
>> 566 if ( (got_what_before != GOT_SPACE) )
>> 567 sos_cpu_kstate_switch(& st_lexer, st_parser);
>> 568
>> 569
>> 570 data_lexer_to_parser.type = LEX_END;
>> 571 sos_cpu_kstate_switch(& st_lexer, st_parser);
>> 572
>> 573
>> 574
>> 575 sos_bochs_printf("Error: end of string already reached !\n");
>> 576 sos_cpu_kstate_switch(& st_lexer, st_main);
250 } 577 }
251 578
252 579
253 static void test_thread() !! 580
>> 581
>> 582
>> 583 struct syntax_node
254 { 584 {
255 !! 585 enum { YY_IS_BINOP, YY_IS_UNAROP, YY_IS_NUM, YY_IS_VAR } type;
256 !! 586 union
257 static struct thr_arg arg_b, arg_c, arg_d, a !! 587 {
258 sos_ui32_t flags; !! 588 int number;
>> 589 char var[STR_VAR_MAXLEN];
>> 590 struct
>> 591 {
>> 592 char op;
>> 593 struct syntax_node *parm_left, *parm_right;
>> 594 } binop;
>> 595 struct
>> 596 {
>> 597 char op;
>> 598 struct syntax_node *parm;
>> 599 } unarop;
>> 600 };
>> 601 };
259 602
260 sos_disable_IRQs(flags); !! 603 static void func_parser(struct syntax_node ** syntax_tree)
>> 604 {
>> 605 static struct syntax_node *alloc_node_num(int val);
>> 606 static struct syntax_node *alloc_node_var(const char * name);
>> 607 static struct syntax_node *alloc_node_binop(char op,
>> 608 struct syntax_node *parm_left,
>> 609 struct syntax_node *parm_right);
>> 610 static struct syntax_node *alloc_node_unarop(char op,
>> 611 struct syntax_node *parm);
>> 612 static struct syntax_node * get_expr();
>> 613 static struct syntax_node * get_expr_lr(struct syntax_node *n);
>> 614 static struct syntax_node * get_term();
>> 615 static struct syntax_node * get_term_lr(struct syntax_node *n);
>> 616 static struct syntax_node * get_factor();
>> 617 static struct syntax_node * get_scalar();
261 618
262 arg_b = (struct thr_arg) { .character='b', . !! 619
263 sos_create_kernel_thread("YO[b]", demo_threa !! 620 static struct syntax_node *alloc_node_num(int val)
>> 621 {
>> 622 struct syntax_node *n
>> 623 = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
>> 624 n->type = YY_IS_NUM;
>> 625 n->number = val;
>> 626 return n;
>> 627 }
>> 628
>> 629 static struct syntax_node *alloc_node_var(const char * name)
>> 630 {
>> 631 struct syntax_node *n
>> 632 = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
>> 633 n->type = YY_IS_VAR;
>> 634 strzcpy(n->var, name, STR_VAR_MAXLEN);
>> 635 return n;
>> 636 }
>> 637
>> 638 static struct syntax_node *alloc_node_binop(char op,
>> 639 struct syntax_node *parm_left,
>> 640 struct syntax_node *parm_right)
>> 641 {
>> 642 struct syntax_node *n
>> 643 = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
>> 644 n->type = YY_IS_BINOP;
>> 645 n->binop.op = op;
>> 646 n->binop.parm_left = parm_left;
>> 647 n->binop.parm_right = parm_right;
>> 648 return n;
>> 649 }
>> 650
>> 651 static struct syntax_node *alloc_node_unarop(char op,
>> 652 struct syntax_node *parm)
>> 653 {
>> 654 struct syntax_node *n
>> 655 = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
>> 656 n->type = YY_IS_UNAROP;
>> 657 n->unarop.op = op;
>> 658 n->unarop.parm = parm;
>> 659 return n;
>> 660 }
264 661
265 arg_c = (struct thr_arg) { .character='c', . !! 662
266 sos_create_kernel_thread("YO[c]", demo_threa !! 663
>> 664 static void parser_exception(const char *str)
>> 665 {
>> 666 sos_bochs_printf("Parser exception: %s\n", str);
>> 667 sos_cpu_kstate_switch(& st_parser, st_main);
>> 668 }
267 669
268 arg_d = (struct thr_arg) { .character='d', . !! 670
269 sos_create_kernel_thread("YO[d]", demo_threa !! 671
>> 672 static int get_number()
>> 673 {
>> 674 int v;
>> 675 if (data_lexer_to_parser.type != LEX_IS_NUMBER)
>> 676 parser_exception("Expected number");
>> 677 v = data_lexer_to_parser.number;
>> 678 sos_cpu_kstate_switch(& st_parser, st_lexer);
>> 679 return v;
>> 680 }
>> 681
>> 682
>> 683 static void get_str(char name[STR_VAR_MAXLEN])
>> 684 {
>> 685 if (data_lexer_to_parser.type != LEX_IS_VAR)
>> 686 parser_exception("Expected variable");
>> 687 strzcpy(name, data_lexer_to_parser.var, STR_VAR_MAXLEN);
>> 688 sos_cpu_kstate_switch(& st_parser, st_lexer);
>> 689 }
>> 690
>> 691
>> 692 static char get_op()
>> 693 {
>> 694 char op;
>> 695 if (data_lexer_to_parser.type != LEX_IS_OPER)
>> 696 parser_exception("Expected operator");
>> 697 op = data_lexer_to_parser.operator;
>> 698 sos_cpu_kstate_switch(& st_parser, st_lexer);
>> 699 return op;
>> 700 }
>> 701
>> 702
>> 703 static void get_par()
>> 704 {
>> 705 if ( (data_lexer_to_parser.type != LEX_IS_OPENPAR)
>> 706 && (data_lexer_to_parser.type != LEX_IS_CLOSEPAR) )
>> 707 parser_exception("Expected parenthese");
>> 708 sos_cpu_kstate_switch(& st_parser, st_lexer);
>> 709 }
270 710
271 arg_e = (struct thr_arg) { .character='e', . !! 711
272 sos_create_kernel_thread("YO[e]", demo_threa !! 712 static struct syntax_node * get_expr()
>> 713 {
>> 714 struct syntax_node *t = get_term();
>> 715 return get_expr_lr(t);
>> 716 }
>> 717
>> 718 static struct syntax_node * get_expr_lr(struct syntax_node *n)
>> 719 {
>> 720 if ( (data_lexer_to_parser.type == LEX_IS_OPER)
>> 721 && ( (data_lexer_to_parser.operator == '+')
>> 722 || (data_lexer_to_parser.operator == '-') ) )
>> 723 {
>> 724 char op = get_op();
>> 725 struct syntax_node *term = get_term();
>> 726 struct syntax_node *node_op = alloc_node_binop(op, n, term);
>> 727 return get_expr_lr(node_op);
>> 728 }
>> 729 return n;
>> 730 }
>> 731
>> 732 static struct syntax_node * get_term()
>> 733 {
>> 734 struct syntax_node *f1 = get_factor();
>> 735 return get_term_lr(f1);
>> 736 }
>> 737
>> 738 static struct syntax_node * get_term_lr(struct syntax_node *n)
>> 739 {
>> 740 if ( (data_lexer_to_parser.type == LEX_IS_OPER)
>> 741 && ( (data_lexer_to_parser.operator == '*')
>> 742 || (data_lexer_to_parser.operator == '/') ) )
>> 743 {
>> 744 char op = get_op();
>> 745 struct syntax_node *factor = get_factor();
>> 746 struct syntax_node *node_op = alloc_node_binop(op, n, factor);
>> 747 return get_term_lr(node_op);
>> 748 }
>> 749 return n;
>> 750 }
>> 751
>> 752 static struct syntax_node * get_factor()
>> 753 {
>> 754 if ( (data_lexer_to_parser.type == LEX_IS_OPER)
>> 755 && ( (data_lexer_to_parser.operator == '-')
>> 756 || (data_lexer_to_parser.operator == '+') ) )
>> 757 { char op = data_lexer_to_parser.operator;
>> 758 get_op(); return alloc_node_unarop(op, get_factor()); }
>> 759 else if (data_lexer_to_parser.type == LEX_IS_OPENPAR)
>> 760 {
>> 761 struct syntax_node *expr;
>> 762 get_par();
>> 763 expr = get_expr();
>> 764 if (data_lexer_to_parser.type != LEX_IS_CLOSEPAR)
>> 765 parser_exception("Mismatched parentheses");
>> 766 get_par();
>> 767 return expr;
>> 768 }
>> 769
>> 770 return get_scalar();
>> 771 }
>> 772
>> 773 static struct syntax_node * get_scalar()
>> 774 {
>> 775 if (data_lexer_to_parser.type != LEX_IS_NUMBER)
>> 776 {
>> 777 char var[STR_VAR_MAXLEN];
>> 778 get_str(var);
>> 779 return alloc_node_var(var);
>> 780 }
>> 781 return alloc_node_num(get_number());
>> 782 }
273 783
274 arg_R = (struct thr_arg) { .character='R', . <<
275 sos_create_kernel_thread("YO[R]", demo_threa <<
276 784
277 arg_S = (struct thr_arg) { .character='S', . !! 785
278 sos_create_kernel_thread("YO[S]", demo_threa !! 786
>> 787
>> 788
>> 789
>> 790 sos_cpu_kstate_switch(& st_parser, st_lexer);
279 791
280 sos_restore_IRQs(flags); !! 792
>> 793 *syntax_tree = get_expr();
>> 794
281 } 795 }
282 796
283 797
284 !! 798
285 !! 799
286 !! 800
>> 801 static struct syntax_node * parse_expression(const char *expr)
>> 802 {
>> 803 struct syntax_node *retval = NULL;
>> 804
>> 805
>> 806 sos_cpu_kstate_init(& st_reader,
>> 807 (sos_cpu_kstate_function_arg1_t*)func_reader,
>> 808 (sos_ui32_t)expr,
>> 809 (sos_vaddr_t)stack_reader, sizeof(stack_reader),
>> 810 (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
>> 811 sos_cpu_kstate_init(& st_lexer,
>> 812 (sos_cpu_kstate_function_arg1_t*)func_lexer,
>> 813 0,
>> 814 (sos_vaddr_t)stack_lexer, sizeof(stack_lexer),
>> 815 (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
>> 816 sos_cpu_kstate_init(& st_parser,
>> 817 (sos_cpu_kstate_function_arg1_t*)func_parser,
>> 818 (sos_ui32_t) &retval,
>> 819 (sos_vaddr_t)deep_stack, sizeof(deep_stack),
>> 820 (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
>> 821
>> 822
>> 823 sos_cpu_kstate_switch(& st_main, st_parser);
>> 824 return retval;
>> 825 }
>> 826
>> 827
>> 828
>> 829
287 830
288 static void idle_thread() !! 831 struct func_eval_params
289 { 832 {
290 sos_ui32_t idle_twiddle = 0; !! 833 const struct syntax_node *e;
>> 834 const char **var_name;
>> 835 int *var_val;
>> 836 int nb_vars;
>> 837
>> 838 int result;
>> 839 };
291 840
292 while (1) !! 841 static void func_eval(struct func_eval_params *parms)
>> 842 {
>> 843
>> 844
>> 845 static int rec_eval(const struct syntax_node *n,
>> 846 const char* var_name[], int var_val[], int nb_vars)
293 { 847 {
294 !! 848 switch (n->type)
295 !! 849 {
296 asm("hlt\n"); !! 850 case YY_IS_NUM:
>> 851 return n->number;
297 852
298 idle_twiddle ++; !! 853 case YY_IS_VAR:
299 display_bits(0, 0, SOS_X86_VIDEO_FG_GREE !! 854 {
300 idle_twiddle); !! 855 int i;
>> 856 for (i = 0 ; i < nb_vars ; i++)
>> 857 if (0 == strcmp(var_name[i], n->var))
>> 858 return var_val[i];
>> 859
>> 860
>> 861 sos_bochs_printf("ERROR: unknown variable %s\n", n->var);
>> 862 sos_cpu_kstate_switch(& st_eval, st_main);
>> 863 }
>> 864
>> 865 case YY_IS_BINOP:
>> 866 {
>> 867 int left = rec_eval(n->binop.parm_left,
>> 868 var_name, var_val, nb_vars);
>> 869 int right = rec_eval(n->binop.parm_right,
>> 870 var_name, var_val, nb_vars);
>> 871 switch (n->binop.op)
>> 872 {
>> 873 case '+': return left + right;
>> 874 case '-': return left - right;
>> 875 case '*': return left * right;
>> 876 case '/': return left / right;
>> 877 default:
>> 878
>> 879 sos_bochs_printf("ERROR: unknown binop %c\n", n->binop.op);
>> 880 sos_cpu_kstate_switch(& st_eval, st_main);
>> 881 }
>> 882 }
>> 883
>> 884 case YY_IS_UNAROP:
>> 885 {
>> 886 int arg = rec_eval(n->unarop.parm, var_name, var_val, nb_vars);
>> 887 switch (n->unarop.op)
>> 888 {
>> 889 case '-': return -arg;
>> 890 case '+': return arg;
>> 891 default:
>> 892
>> 893 sos_bochs_printf("ERROR: unknown unarop %c\n", n->unarop.op);
>> 894 sos_cpu_kstate_switch(& st_eval, st_main);
>> 895 }
>> 896 }
>> 897 }
301 898
302 !! 899
303 sos_thread_yield(); !! 900 sos_bochs_printf("ERROR: invalid node type\n");
>> 901 sos_cpu_kstate_switch(& st_eval, st_main);
>> 902 return -1;
304 } 903 }
>> 904
>> 905
>> 906
>> 907
>> 908
>> 909
>> 910 parms->result
>> 911 = rec_eval(parms->e, parms->var_name, parms->var_val, parms->nb_vars);
>> 912 }
>> 913
>> 914
>> 915
>> 916
>> 917
>> 918 static int eval_expression(const struct syntax_node *e,
>> 919 const char* var_name[], int var_val[], int nb_vars)
>> 920 {
>> 921 struct func_eval_params p
>> 922 = (struct func_eval_params){ .e=e,
>> 923 .var_name=var_name,
>> 924 .var_val=var_val,
>> 925 .nb_vars=nb_vars,
>> 926 .result = 0 };
>> 927
>> 928 sos_cpu_kstate_init(& st_eval,
>> 929 (sos_cpu_kstate_function_arg1_t*)func_eval,
>> 930 (sos_ui32_t)&p,
>> 931 (sos_vaddr_t)deep_stack, sizeof(deep_stack),
>> 932 (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
>> 933
>> 934
>> 935 sos_cpu_kstate_switch(& st_main, st_eval);
>> 936 return p.result;
>> 937 }
>> 938
>> 939
>> 940
>> 941
>> 942
>> 943 static void func_free(struct syntax_node *n)
>> 944 {
>> 945 switch (n->type)
>> 946 {
>> 947 case YY_IS_NUM:
>> 948 case YY_IS_VAR:
>> 949 break;
>> 950
>> 951 case YY_IS_BINOP:
>> 952 func_free(n->binop.parm_left);
>> 953 func_free(n->binop.parm_right);
>> 954 break;
>> 955
>> 956 case YY_IS_UNAROP:
>> 957 func_free(n->unarop.parm);
>> 958 break;
>> 959 }
>> 960
>> 961 sos_kfree((sos_vaddr_t)n);
>> 962 }
>> 963
>> 964
>> 965
>> 966
>> 967
>> 968 static void free_syntax_tree(struct syntax_node *tree)
>> 969 {
>> 970 sos_cpu_kstate_init(& st_free,
>> 971 (sos_cpu_kstate_function_arg1_t*)func_free,
>> 972 (sos_ui32_t)tree,
>> 973 (sos_vaddr_t)deep_stack, sizeof(deep_stack),
>> 974 (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
>> 975
>> 976
>> 977 sos_cpu_kstate_switch(& st_main, st_free);
305 } 978 }
306 979
307 980
308 981
309 982
310 983
311 void sos_main(unsigned long magic, unsigned lo 984 void sos_main(unsigned long magic, unsigned long addr)
312 { 985 {
313 unsigned i; 986 unsigned i;
314 sos_paddr_t sos_kernel_core_base_paddr, sos_ 987 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
315 struct sos_time tick_resolution; !! 988 struct syntax_node *syntax_tree;
316 989
317 990
318 991
319 992
320 multiboot_info_t *mbi; 993 multiboot_info_t *mbi;
321 mbi = (multiboot_info_t *) addr; 994 mbi = (multiboot_info_t *) addr;
322 995
323 996
324 sos_bochs_setup(); 997 sos_bochs_setup();
325 998
326 sos_x86_videomem_setup(); 999 sos_x86_videomem_setup();
327 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 1000 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
328 1001
329 1002
330 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 1003 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
331 1004
332 sos_x86_videomem_printf(1, 0, 1005 sos_x86_videomem_printf(1, 0,
333 SOS_X86_VIDEO_FG_Y 1006 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
334 "Welcome From GRUB 1007 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
335 "SOS article 6.5", !! 1008 "SOS", ',',
336 (unsigned)(mbi->me 1009 (unsigned)(mbi->mem_upper >> 10) + 1,
337 (unsigned)mbi->mem 1010 (unsigned)mbi->mem_upper);
338 else 1011 else
339 1012
340 sos_x86_videomem_printf(1, 0, 1013 sos_x86_videomem_printf(1, 0,
341 SOS_X86_VIDEO_FG_Y 1014 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
342 "Welcome to SOS ar !! 1015 "Welcome to SOS");
343 1016
344 sos_bochs_putstring("Message in a bochs: Thi !! 1017 sos_bochs_putstring("Message in a bochs\n");
345 1018
346 1019
347 sos_gdt_subsystem_setup(); 1020 sos_gdt_subsystem_setup();
348 sos_idt_subsystem_setup(); 1021 sos_idt_subsystem_setup();
349 1022
350 1023
351 sos_exception_subsystem_setup(); 1024 sos_exception_subsystem_setup();
352 sos_irq_subsystem_setup(); 1025 sos_irq_subsystem_setup();
353 1026
354 1027
355 sos_i8254_set_frequency(100); 1028 sos_i8254_set_frequency(100);
356 1029
357 <<
358 <<
359 tick_resolution = (struct sos_time) { .sec=0 <<
360 sos_time_subsysem_setup(& tick_resolution); <<
361 <<
362 1030
363 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 1031 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
364 { 1032 {
365 sos_x86_videomem_putstring(20, 0, 1033 sos_x86_videomem_putstring(20, 0,
366 SOS_X86_VIDEO 1034 SOS_X86_VIDEO_FG_LTRED
367 | SOS_X86_V 1035 | SOS_X86_VIDEO_BG_BLUE
368 | SOS_X86_V 1036 | SOS_X86_VIDEO_FG_BLINKING,
369 "I'm not load 1037 "I'm not loaded with Grub !");
370 1038
371 for (;;) 1039 for (;;)
372 continue; 1040 continue;
373 } 1041 }
374 1042
375 1043
376 1044
377 1045
378 1046
379 1047
380 sos_irq_set_routine(SOS_IRQ_TIMER, 1048 sos_irq_set_routine(SOS_IRQ_TIMER,
381 clk_it); 1049 clk_it);
382 1050
383 1051
384 1052
385 1053
386 1054
387 1055
388 1056
389 1057
390 sos_physmem_subsystem_setup((mbi->mem_upper< 1058 sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
391 & sos_kernel_cor 1059 & sos_kernel_core_base_paddr,
392 & sos_kernel_cor 1060 & sos_kernel_core_top_paddr);
393 1061
394 1062
395 1063
396 1064
397 1065
398 1066
399 1067
400 SOS_ASSERT_FATAL(SOS_OK == 1068 SOS_ASSERT_FATAL(SOS_OK ==
401 sos_paging_subsystem_setup( 1069 sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
402 1070 sos_kernel_core_top_paddr));
403 1071
404 1072
405 sos_exception_set_routine(SOS_EXCEPT_PAGE_FA 1073 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
406 pgflt_ex); 1074 pgflt_ex);
407 1075
408 1076
409 1077
410 !! 1078
411 1079
412 if (sos_kmem_vmm_subsystem_setup(sos_kernel_ 1080 if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
413 sos_kernel_ 1081 sos_kernel_core_top_paddr,
414 bootstrap_s 1082 bootstrap_stack_bottom,
415 bootstrap_s 1083 bootstrap_stack_bottom
416 + bootstrap 1084 + bootstrap_stack_size))
417 sos_bochs_printf("Could not setup the Kern 1085 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
418 1086
419 if (sos_kmalloc_subsystem_setup()) 1087 if (sos_kmalloc_subsystem_setup())
420 sos_bochs_printf("Could not setup the Kmal 1088 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
421 1089
422 1090
423 !! 1091
>> 1092
424 1093
425 !! 1094 asm volatile ("sti\n");
426 <<
427 sos_thread_subsystem_setup(bootstrap_stack_b <<
428 bootstrap_stack_s <<
429 1095
430 !! 1096
431 sos_sched_subsystem_setup(); !! 1097
>> 1098
>> 1099 print_hello_world();
432 1100
433 <<
434 SOS_ASSERT_FATAL(sos_create_kernel_thread("i <<
435 1101
436 !! 1102
437 !! 1103
438 asm volatile ("sti\n"); !! 1104
>> 1105 sos_x86_videomem_printf(4, 0,
>> 1106 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_LTGREEN,
>> 1107 "Coroutine test");
>> 1108 sos_x86_videomem_printf(5, 0,
>> 1109 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 1110 "Parsing...");
>> 1111 syntax_tree = parse_expression(" - ( (69/ toto)+ ( (( - +-- 1))) + --toto*((toto+ - - y - +2*(y-toto))*y) +2*(y-toto) )/- (( y - toto)*2)");
>> 1112
>> 1113 if (syntax_tree != NULL)
>> 1114 {
>> 1115 sos_x86_videomem_printf(6, 0,
>> 1116 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 1117 "Evaluating...");
>> 1118 sos_x86_videomem_printf(7, 0,
>> 1119 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 1120 "Result=%d (if 0: check bochs output)",
>> 1121 eval_expression(syntax_tree,
>> 1122 (const char*[]){"toto", "y"},
>> 1123 (int[]){3, 4},
>> 1124 2));
>> 1125 free_syntax_tree(syntax_tree);
>> 1126 sos_x86_videomem_printf(8, 0,
>> 1127 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 1128 "Done (un-allocated syntax tree)");
>> 1129 }
>> 1130 else
>> 1131 {
>> 1132 sos_x86_videomem_printf(6, 0,
>> 1133 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
>> 1134 "Error in parsing (see bochs output)");
>> 1135 }
>> 1136
>> 1137
>> 1138
>> 1139
>> 1140 test_demand_paging(234567, 500);
>> 1141
>> 1142
>> 1143
>> 1144
>> 1145
>> 1146
>> 1147 test_backtrace(6, 0xdeadbeef, bootstrap_stack_bottom, bootstrap_stack_size);
>> 1148
>> 1149
>> 1150
>> 1151
439 1152
440 1153
441 !! 1154
442 extern void MouseSim(); !! 1155 for (;;)
443 MouseSim(); !! 1156 {
444 test_thread(); !! 1157
445 !! 1158
446 !! 1159 asm("hlt\n");
447 !! 1160
448 !! 1161 continue;
449 !! 1162 }
450 <<
451 <<
452 <<
453 <<
454 <<
455 <<
456 <<
457 <<
458 sos_bochs_printf("Bye from primary thread !\ <<
459 sos_thread_exit(); <<
460 SOS_FATAL_ERROR("No trespassing !"); <<
461 } 1163 }