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 <bootstrap/multiboot.h> 021 #include <bootstrap/multiboot.h>
022 #include <hwcore/idt.h> 022 #include <hwcore/idt.h>
023 #include <hwcore/gdt.h> 023 #include <hwcore/gdt.h>
024 #include <hwcore/irq.h> 024 #include <hwcore/irq.h>
025 #include <hwcore/exception.h> 025 #include <hwcore/exception.h>
026 #include <hwcore/i8254.h> 026 #include <hwcore/i8254.h>
027 #include <sos/list.h> 027 #include <sos/list.h>
028 #include <sos/physmem.h> 028 #include <sos/physmem.h>
029 #include <hwcore/paging.h> 029 #include <hwcore/paging.h>
030 #include <sos/kmem_vmm.h> 030 #include <sos/kmem_vmm.h>
031 #include <sos/kmalloc.h> 031 #include <sos/kmalloc.h>
032 #include <sos/klibc.h> 032 #include <sos/klibc.h>
033 #include <sos/assert.h> 033 #include <sos/assert.h>
034 #include <drivers/x86_videomem.h> 034 #include <drivers/x86_videomem.h>
035 #include <drivers/bochs.h> 035 #include <drivers/bochs.h>
036 036
037 037
038 038
039 039
040 static void display_bits(unsigned char row, un !! 040 void display_bits(unsigned char row, unsigned char col,
041 unsigned char attribu !! 041 unsigned char attribute,
042 sos_ui32_t integer) !! 042 sos_ui32_t integer)
043 { 043 {
044 int i; 044 int i;
045 045
046 for (i = 31 ; i >= 0 ; i--) 046 for (i = 31 ; i >= 0 ; i--)
047 { 047 {
048 048
049 int bit_i = (integer & (1 << i)); 049 int bit_i = (integer & (1 << i));
050 050
051 unsigned char ascii_code = bit_i?219:177 051 unsigned char ascii_code = bit_i?219:177;
052 sos_x86_videomem_putchar(row, col++, 052 sos_x86_videomem_putchar(row, col++,
053 attribute, 053 attribute,
054 ascii_code); 054 ascii_code);
055 } 055 }
056 } 056 }
057 057
058 058
059 059
060 static void clk_it(int intid) !! 060 static void clk_it(int intid,
>> 061 const struct sos_cpu_kstate *cpu_kstate)
061 { 062 {
062 static sos_ui32_t clock_count = 0; 063 static sos_ui32_t clock_count = 0;
063 064
064 display_bits(0, 48, 065 display_bits(0, 48,
065 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 066 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
066 clock_count); 067 clock_count);
067 clock_count++; 068 clock_count++;
068 <<
069 } 069 }
070 struct digit !! 070
>> 071
>> 072
>> 073
>> 074
>> 075
>> 076
>> 077 static void dump_backtrace(const struct sos_cpu_kstate *cpu_kstate,
>> 078 sos_vaddr_t stack_bottom,
>> 079 sos_size_t stack_size,
>> 080 sos_bool_t on_console,
>> 081 sos_bool_t on_bochs)
071 { 082 {
072 struct digit *prev, *next; !! 083 static void backtracer(sos_vaddr_t PC,
073 char value; !! 084 sos_vaddr_t params,
074 }; !! 085 sos_ui32_t depth,
>> 086 void *custom_arg)
>> 087 {
>> 088 sos_ui32_t invalid = 0xffffffff, *arg1, *arg2, *arg3, *arg4;
075 089
076 !! 090
077 !! 091
078 !! 092
079 typedef struct digit * big_number_t; !! 093
>> 094 arg1 = (sos_ui32_t*)params;
>> 095 arg2 = (sos_ui32_t*)(params+4);
>> 096 arg3 = (sos_ui32_t*)(params+8);
>> 097 arg4 = (sos_ui32_t*)(params+12);
>> 098
>> 099
>> 100
>> 101 #define INTERVAL_OK(b,v,u) ( ((b) <= (sos_vaddr_t)(v)) \
>> 102 && ((sos_vaddr_t)(v) < (u)) )
>> 103 if (!INTERVAL_OK(stack_bottom, arg1, stack_bottom + stack_size))
>> 104 arg1 = &invalid;
>> 105 if (!INTERVAL_OK(stack_bottom, arg2, stack_bottom + stack_size))
>> 106 arg2 = &invalid;
>> 107 if (!INTERVAL_OK(stack_bottom, arg3, stack_bottom + stack_size))
>> 108 arg3 = &invalid;
>> 109 if (!INTERVAL_OK(stack_bottom, arg4, stack_bottom + stack_size))
>> 110 arg4 = &invalid;
>> 111
>> 112
>> 113 if (on_bochs)
>> 114 sos_bochs_printf("[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x\n",
>> 115 (unsigned)depth, (unsigned)PC,
>> 116 (unsigned)*arg1, (unsigned)*arg2,
>> 117 (unsigned)*arg3);
>> 118
>> 119 if (on_console)
>> 120 sos_x86_videomem_printf(23-depth, 3,
>> 121 SOS_X86_VIDEO_BG_BLUE
>> 122 | SOS_X86_VIDEO_FG_LTGREEN,
>> 123 "[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x arg4=0x%x",
>> 124 (unsigned)depth, PC,
>> 125 (unsigned)*arg1, (unsigned)*arg2,
>> 126 (unsigned)*arg3, (unsigned)*arg4);
>> 127
>> 128 }
>> 129
>> 130 sos_backtrace(cpu_kstate, 15, stack_bottom, stack_size, backtracer, NULL);
>> 131 }
080 132
081 133
082 !! 134
083 void bn_push_lsd(big_number_t * bn, char value !! 135 static void pgflt_ex(int intid, const struct sos_cpu_kstate *ctxt)
084 { 136 {
085 struct digit *d; !! 137 static sos_ui32_t demand_paging_count = 0;
086 d = (struct digit*) sos_kmalloc(sizeof(struc !! 138 sos_vaddr_t faulting_vaddr = sos_cpu_kstate_get_EX_faulting_vaddr(ctxt);
087 SOS_ASSERT_FATAL(d != NULL); !! 139 sos_paddr_t ppage_paddr;
088 d->value = value; !! 140
089 list_add_tail(*bn, d); !! 141
>> 142 if (! sos_kmem_vmm_is_valid_vaddr(faulting_vaddr))
>> 143 {
>> 144
>> 145
>> 146 dump_backtrace(ctxt,
>> 147 bootstrap_stack_bottom,
>> 148 bootstrap_stack_size,
>> 149 TRUE, TRUE);
>> 150 sos_display_fatal_error("Unresolved page Fault on access to address 0x%x (info=%x)!",
>> 151 (unsigned)faulting_vaddr,
>> 152 (unsigned)sos_cpu_kstate_get_EX_info(ctxt));
>> 153 SOS_ASSERT_FATAL(! "Got page fault (note: demand paging is disabled)");
>> 154 }
>> 155
>> 156
>> 157
>> 158
>> 159
>> 160
>> 161
>> 162 demand_paging_count ++;
>> 163 display_bits(0, 0,
>> 164 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
>> 165 demand_paging_count);
>> 166
>> 167
>> 168 ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
>> 169 if (! ppage_paddr)
>> 170 SOS_ASSERT_FATAL(! "TODO: implement swap. (Out of mem in demand paging because no swap for kernel yet !)");
>> 171 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(ppage_paddr,
>> 172 SOS_PAGE_ALIGN_INF(faulting_vaddr),
>> 173 FALSE,
>> 174 SOS_VM_MAP_PROT_READ
>> 175 | SOS_VM_MAP_PROT_WRITE
>> 176 | SOS_VM_MAP_ATOMIC));
>> 177 sos_physmem_unref_physpage(ppage_paddr);
>> 178
>> 179
090 } 180 }
091 181
092 182
093 !! 183
094 void bn_push_msd(big_number_t * bn, char value !! 184
>> 185
>> 186
>> 187
>> 188
>> 189
>> 190
>> 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;
>> 196
>> 197 static void reclaim_stack(sos_vaddr_t stack_vaddr)
095 { 198 {
096 struct digit *d; !! 199 sos_kfree(stack_vaddr);
097 d = (struct digit*) sos_kmalloc(sizeof(struc <<
098 SOS_ASSERT_FATAL(d != NULL); <<
099 d->value = value; <<
100 list_add_head(*bn, d); <<
101 } 200 }
102 201
103 202
104 !! 203 static void exit_hello12(sos_vaddr_t stack_vaddr)
105 big_number_t bn_new(unsigned long int i) <<
106 { 204 {
107 big_number_t retval; !! 205 sos_cpu_kstate_exit_to(ctxt_main,
>> 206 (sos_cpu_kstate_function_arg1_t*) reclaim_stack,
>> 207 stack_vaddr);
>> 208 }
108 209
109 list_init(retval); !! 210
110 do !! 211 static void hello1 (char *str)
>> 212 {
>> 213 for ( ; *str != '\n' ; str++)
111 { 214 {
112 bn_push_msd(&retval, i%10); !! 215 sos_bochs_printf("hello1: %c\n", *str);
113 i /= 10; !! 216 sos_cpu_kstate_switch(& ctxt_hello1, ctxt_hello2);
114 } 217 }
115 while (i != 0); <<
116 218
117 return retval; !! 219
>> 220
>> 221
>> 222
>> 223
118 } 224 }
119 225
120 226
121 !! 227 static void hello2 (char *str)
122 big_number_t bn_copy(const big_number_t bn) <<
123 { 228 {
124 big_number_t retval; !! 229 for ( ; *str != '\n' ; str++)
125 int nb_elts; <<
126 struct digit *d; <<
127 <<
128 list_init(retval); <<
129 list_foreach(bn, d, nb_elts) <<
130 { 230 {
131 bn_push_lsd(&retval, d->value); !! 231 sos_bochs_printf("hello2: %c\n", *str);
>> 232 sos_cpu_kstate_switch(& ctxt_hello2, ctxt_hello1);
132 } 233 }
133 234
134 return retval; !! 235
>> 236
>> 237
>> 238
>> 239
135 } 240 }
136 241
137 242
138 !! 243 void print_hello_world ()
139 void bn_del(big_number_t * bn) <<
140 { 244 {
141 struct digit *d; !! 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);
142 267
143 list_collapse(*bn, d) !! 268
144 { !! 269 sos_bochs_printf("Back in main !\n");
145 sos_kfree((sos_vaddr_t)d); <<
146 } <<
147 } 270 }
148 271
149 272
150 !! 273
151 void bn_shift(big_number_t *bn, int shift) !! 274
>> 275
>> 276
>> 277
>> 278 static void test_demand_paging(int nb_alloc_vpages, int nb_alloc_ppages)
152 { 279 {
153 for ( ; shift > 0 ; shift --) !! 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++)
154 { 300 {
155 bn_push_lsd(bn, 0); !! 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);
156 } 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)");
157 } 328 }
158 329
159 330
160 !! 331
161 void bn_print_bochs(const big_number_t bn) !! 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)
162 { 339 {
163 int nb_elts; !! 340 if (i <= 0)
164 const struct digit *d; !! 341 {
>> 342
>> 343
>> 344 *((char*)0x42) = 12;
165 345
166 if (list_is_empty(bn)) !! 346
167 sos_bochs_printf("0"); !! 347
>> 348 }
168 else 349 else
169 list_foreach(bn, d, nb_elts) !! 350 test_backtrace(i-1, magic, stack_bottom, stack_size);
170 sos_bochs_printf("%d", d->value); <<
171 } 351 }
172 352
173 !! 353
174 void bn_print_console(unsigned char row, unsig !! 354
175 unsigned char attribute, !! 355
176 const big_number_t bn, !! 356
177 int nb_decimals) !! 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
>> 432
>> 433
>> 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)
178 { 449 {
179 if (list_is_empty(bn)) !! 450 }
180 sos_x86_videomem_printf(row, col, attribut !! 451 static void func_exit(sos_ui32_t unused)
181 else !! 452 {
182 { !! 453 sos_cpu_kstate_exit_to(st_main, (sos_cpu_kstate_function_arg1_t*)reclaim, 0);
183 int nb_elts; !! 454 }
184 const struct digit *d; <<
185 unsigned char x = col; <<
186 455
187 list_foreach(bn, d, nb_elts) <<
188 { <<
189 if (nb_elts == 0) <<
190 { <<
191 sos_x86_videomem_printf(row, x, <<
192 x += 2; <<
193 } <<
194 else if (nb_elts < nb_decimals) <<
195 { <<
196 sos_x86_videomem_printf(row, x, <<
197 x ++; <<
198 } <<
199 } <<
200 456
201 sos_x86_videomem_printf(row, x, attribut !! 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++)
>> 467 {
>> 468 data_reader_to_lexer = *str;
>> 469 sos_cpu_kstate_switch(& st_reader, st_lexer);
202 } 470 }
>> 471
>> 472 data_reader_to_lexer = '\0';
>> 473 sos_cpu_kstate_switch(& st_reader, st_lexer);
203 } 474 }
204 475
205 476
206 !! 477
207 big_number_t bn_add (const big_number_t bn1, c !! 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;
>> 494
>> 495 static void func_lexer(sos_ui32_t unused)
208 { 496 {
209 big_number_t retval; !! 497 char c;
210 const struct digit *d1, *d2; !! 498 enum { GOT_SPACE, GOT_NUM, GOT_OP, GOT_STR,
211 sos_bool_t bn1_end = FALSE, bn2_end = FALSE !! 499 GOT_OPENPAR, GOT_CLOSEPAR } got_what, got_what_before;
212 char carry = 0; <<
213 500
214 list_init(retval); !! 501 data_lexer_to_parser.number = 0;
215 d1 = list_get_tail(bn1); !! 502 got_what_before = GOT_SPACE;
216 bn1_end = list_is_empty(bn1); <<
217 d2 = list_get_tail(bn2); <<
218 bn2_end = list_is_empty(bn2); <<
219 do 503 do
220 { 504 {
221 if (! bn1_end) !! 505
222 carry += d1->value; !! 506 sos_cpu_kstate_switch(& st_lexer, st_reader);
223 if (! bn2_end) !! 507 c = data_reader_to_lexer;
224 carry += d2->value; !! 508
225 !! 509
226 bn_push_msd(&retval, carry % 10); !! 510 if ( (c >= '0') && (c <= '9') )
227 carry /= 10; !! 511 got_what = GOT_NUM;
228 !! 512 else if ( (c == '+') || (c == '-') || (c == '*') || (c == '/') )
229 if (! bn1_end) !! 513 got_what = GOT_OP;
230 d1 = d1->prev; !! 514 else if ( ( (c >= 'a') && (c <= 'z') )
231 if (! bn2_end) !! 515 || ( (c >= 'A') && (c <= 'Z') ) )
232 d2 = d2->prev; !! 516 got_what = GOT_STR;
233 if (d1 == list_get_tail(bn1)) !! 517 else if (c == '(')
234 bn1_end = TRUE; !! 518 got_what = GOT_OPENPAR;
235 if (d2 == list_get_tail(bn2)) !! 519 else if (c == ')')
236 bn2_end = TRUE; !! 520 got_what = GOT_CLOSEPAR;
237 } !! 521 else
238 while (!bn1_end || !bn2_end); !! 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) )
>> 529 {
>> 530
>> 531
>> 532 if ( (got_what_before != GOT_SPACE) )
>> 533 sos_cpu_kstate_switch(& st_lexer, st_parser);
239 534
240 if (carry > 0) !! 535 data_lexer_to_parser.number = 0;
241 { !! 536 }
242 bn_push_msd(&retval, carry); !! 537
>> 538
>> 539 if (got_what == GOT_OP)
>> 540 {
>> 541 data_lexer_to_parser.type = LEX_IS_OPER;
>> 542 data_lexer_to_parser.operator = c;
>> 543 }
>> 544 else if (got_what == GOT_NUM)
>> 545 {
>> 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)
>> 551 {
>> 552 char to_cat[] = { c, '\0' };
>> 553 data_lexer_to_parser.type = LEX_IS_VAR;
>> 554 strzcat(data_lexer_to_parser.var, to_cat, STR_VAR_MAXLEN);
>> 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;
>> 560
>> 561 got_what_before = got_what;
243 } 562 }
>> 563 while (c != '\0');
244 564
245 return retval; !! 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);
246 } 577 }
247 578
248 579
249 !! 580
250 big_number_t bn_muli (const big_number_t bn, c !! 581
>> 582
>> 583 struct syntax_node
251 { 584 {
252 big_number_t retval; !! 585 enum { YY_IS_BINOP, YY_IS_UNAROP, YY_IS_NUM, YY_IS_VAR } type;
253 int nb_elts; !! 586 union
254 char carry = 0; !! 587 {
255 const struct digit *d; !! 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 };
256 602
257 list_init(retval); !! 603 static void func_parser(struct syntax_node ** syntax_tree)
258 list_foreach_backward(bn, d, nb_elts) !! 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();
>> 618
>> 619
>> 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)
259 { 641 {
260 carry += d->value * digit; !! 642 struct syntax_node *n
261 bn_push_msd(&retval, carry % 10); !! 643 = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
262 carry /= 10; !! 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;
263 } 660 }
264 661
265 if (carry > 0) !! 662
>> 663
>> 664 static void parser_exception(const char *str)
266 { 665 {
267 bn_push_msd(&retval, carry); !! 666 sos_bochs_printf("Parser exception: %s\n", str);
>> 667 sos_cpu_kstate_switch(& st_parser, st_main);
268 } 668 }
269 669
270 return retval; !! 670
>> 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 }
>> 710
>> 711
>> 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 }
>> 783
>> 784
>> 785
>> 786
>> 787
>> 788
>> 789
>> 790 sos_cpu_kstate_switch(& st_parser, st_lexer);
>> 791
>> 792
>> 793 *syntax_tree = get_expr();
>> 794
271 } 795 }
272 796
273 797
274 !! 798
275 big_number_t bn_mult(const big_number_t bn1, c !! 799
>> 800
>> 801 static struct syntax_node * parse_expression(const char *expr)
276 { 802 {
277 int shift = 0; !! 803 struct syntax_node *retval = NULL;
278 big_number_t retval; <<
279 int nb_elts; <<
280 struct digit *d; <<
281 <<
282 list_init(retval); <<
283 list_foreach_backward(bn2, d, nb_elts) <<
284 { <<
285 big_number_t retmult = bn_muli(bn1, d->v <<
286 big_number_t old_retval = retval; <<
287 bn_shift(& retmult, shift); <<
288 retval = bn_add(old_retval, retmult); <<
289 bn_del(& retmult); <<
290 bn_del(& old_retval); <<
291 shift ++; <<
292 } <<
293 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);
294 return retval; 824 return retval;
295 } 825 }
296 826
297 827
298 !! 828
299 big_number_t bn_fact(unsigned long int v) !! 829
>> 830
>> 831 struct func_eval_params
300 { 832 {
301 unsigned long int i; !! 833 const struct syntax_node *e;
302 big_number_t retval = bn_new(1); !! 834 const char **var_name;
303 for (i = 1 ; i <= v ; i++) !! 835 int *var_val;
304 { !! 836 int nb_vars;
305 big_number_t I = bn_new(i); !! 837
306 big_number_t tmp = bn_mult(retval, I); !! 838 int result;
307 sos_x86_videomem_printf(4, 0, !! 839 };
308 SOS_X86_VIDEO_BG !! 840
309 "%d! = ", (int)i !! 841 static void func_eval(struct func_eval_params *parms)
310 bn_print_console(4, 8, SOS_X86_VIDEO_BG_ !! 842 {
311 tmp, 55); !! 843
312 bn_del(& I); !! 844
313 bn_del(& retval); !! 845 static int rec_eval(const struct syntax_node *n,
314 retval = tmp; !! 846 const char* var_name[], int var_val[], int nb_vars)
>> 847 {
>> 848 switch (n->type)
>> 849 {
>> 850 case YY_IS_NUM:
>> 851 return n->number;
>> 852
>> 853 case YY_IS_VAR:
>> 854 {
>> 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 }
>> 898
>> 899
>> 900 sos_bochs_printf("ERROR: invalid node type\n");
>> 901 sos_cpu_kstate_switch(& st_eval, st_main);
>> 902 return -1;
315 } 903 }
316 904
317 return retval; !! 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;
318 } 937 }
319 938
320 939
321 void bn_test() !! 940
>> 941
>> 942
>> 943 static void func_free(struct syntax_node *n)
322 { 944 {
323 big_number_t bn = bn_fact(1000); !! 945 switch (n->type)
324 sos_bochs_printf("1000! = "); !! 946 {
325 bn_print_bochs(bn); !! 947 case YY_IS_NUM:
326 sos_bochs_printf("\n"); !! 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 }
327 960
>> 961 sos_kfree((sos_vaddr_t)n);
328 } 962 }
329 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);
330 975
331 !! 976
>> 977 sos_cpu_kstate_switch(& st_main, st_free);
>> 978 }
>> 979
>> 980
>> 981
>> 982
>> 983
332 void sos_main(unsigned long magic, unsigned lo 984 void sos_main(unsigned long magic, unsigned long addr)
333 { 985 {
334 unsigned i; 986 unsigned i;
335 sos_paddr_t sos_kernel_core_base_paddr, sos_ 987 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
>> 988 struct syntax_node *syntax_tree;
336 989
337 990
338 991
339 992
340 multiboot_info_t *mbi; 993 multiboot_info_t *mbi;
341 mbi = (multiboot_info_t *) addr; 994 mbi = (multiboot_info_t *) addr;
342 995
343 996
344 sos_bochs_setup(); 997 sos_bochs_setup();
345 998
346 sos_x86_videomem_setup(); 999 sos_x86_videomem_setup();
347 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 1000 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
348 1001
349 1002
350 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 1003 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
351 1004
352 sos_x86_videomem_printf(1, 0, 1005 sos_x86_videomem_printf(1, 0,
353 SOS_X86_VIDEO_FG_Y 1006 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
354 "Welcome From GRUB 1007 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
355 "SOS", ',', 1008 "SOS", ',',
356 (unsigned)(mbi->me 1009 (unsigned)(mbi->mem_upper >> 10) + 1,
357 (unsigned)mbi->mem 1010 (unsigned)mbi->mem_upper);
358 else 1011 else
359 1012
360 sos_x86_videomem_printf(1, 0, 1013 sos_x86_videomem_printf(1, 0,
361 SOS_X86_VIDEO_FG_Y 1014 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
362 "Welcome to SOS"); 1015 "Welcome to SOS");
363 1016
364 sos_bochs_putstring("Message in a bochs\n"); 1017 sos_bochs_putstring("Message in a bochs\n");
365 1018
366 1019
367 sos_gdt_setup(); !! 1020 sos_gdt_subsystem_setup();
368 sos_idt_setup(); !! 1021 sos_idt_subsystem_setup();
369 1022
370 1023
371 sos_exceptions_setup(); !! 1024 sos_exception_subsystem_setup();
372 sos_irq_setup(); !! 1025 sos_irq_subsystem_setup();
373 1026
374 1027
375 sos_i8254_set_frequency(100); 1028 sos_i8254_set_frequency(100);
376 1029
377 <<
378 1030
379 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 1031 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
380 { 1032 {
381 sos_x86_videomem_putstring(20, 0, 1033 sos_x86_videomem_putstring(20, 0,
382 SOS_X86_VIDEO 1034 SOS_X86_VIDEO_FG_LTRED
383 | SOS_X86_V 1035 | SOS_X86_VIDEO_BG_BLUE
384 | SOS_X86_V 1036 | SOS_X86_VIDEO_FG_BLINKING,
385 "I'm not load 1037 "I'm not loaded with Grub !");
386 1038
387 for (;;) 1039 for (;;)
388 continue; 1040 continue;
389 } 1041 }
390 1042
>> 1043
>> 1044
>> 1045
>> 1046
391 1047
392 sos_irq_set_routine(SOS_IRQ_TIMER, 1048 sos_irq_set_routine(SOS_IRQ_TIMER,
393 clk_it); !! 1049 clk_it);
394 !! 1050
395 !! 1051
396 asm volatile ("sti\n"); !! 1052
>> 1053
>> 1054
397 1055
398 1056
399 1057
400 sos_physmem_setup((mbi->mem_upper<<10) + (1< !! 1058 sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
401 & sos_kernel_core_base_pad !! 1059 & sos_kernel_core_base_paddr,
402 & sos_kernel_core_top_padd !! 1060 & sos_kernel_core_top_paddr);
403 1061
404 1062
405 1063
406 1064
407 1065
408 1066
409 1067
410 if (sos_paging_setup(sos_kernel_core_base_pa !! 1068 SOS_ASSERT_FATAL(SOS_OK ==
411 sos_kernel_core_top_pad !! 1069 sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
412 sos_bochs_printf("Could not setup paged me !! 1070 sos_kernel_core_top_paddr));
413 sos_x86_videomem_printf(2, 0, !! 1071
414 SOS_X86_VIDEO_FG_YEL !! 1072
415 "Paged-memory mode i !! 1073 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
>> 1074 pgflt_ex);
416 1075
>> 1076
>> 1077
>> 1078
417 1079
418 if (sos_kmem_vmm_setup(sos_kernel_core_base_ !! 1080 if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
419 sos_kernel_core_top_p !! 1081 sos_kernel_core_top_paddr,
>> 1082 bootstrap_stack_bottom,
>> 1083 bootstrap_stack_bottom
>> 1084 + bootstrap_stack_size))
420 sos_bochs_printf("Could not setup the Kern 1085 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
421 1086
422 if (sos_kmalloc_setup()) !! 1087 if (sos_kmalloc_subsystem_setup())
423 sos_bochs_printf("Could not setup the Kmal 1088 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
424 1089
425 !! 1090
426 bn_test(); !! 1091
>> 1092
>> 1093
>> 1094 asm volatile ("sti\n");
>> 1095
>> 1096
>> 1097
>> 1098
>> 1099 print_hello_world();
>> 1100
>> 1101
>> 1102
>> 1103
>> 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
>> 1152
427 1153
428 1154
429 for (;;) 1155 for (;;)
430 continue; !! 1156 {
>> 1157
>> 1158
>> 1159 asm("hlt\n");
431 1160
432 return; !! 1161 continue;
>> 1162 }
433 } 1163 }