001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021 #include <bootstrap/multiboot.h>
022 #include <hwcore/idt.h>
023 #include <hwcore/gdt.h>
024 #include <hwcore/irq.h>
025 #include <hwcore/exception.h>
026 #include <hwcore/i8254.h>
027 #include <sos/list.h>
028 #include <sos/physmem.h>
029 #include <hwcore/paging.h>
030 #include <sos/kmem_vmm.h>
031 #include <sos/kmalloc.h>
032 #include <sos/klibc.h>
033 #include <sos/assert.h>
034 #include <drivers/x86_videomem.h>
035 #include <drivers/bochs.h>
036
037
038
039
040 void display_bits(unsigned char row, unsigned char col,
041 unsigned char attribute,
042 sos_ui32_t integer)
043 {
044 int i;
045
046 for (i = 31 ; i >= 0 ; i--)
047 {
048
049 int bit_i = (integer & (1 << i));
050
051 unsigned char ascii_code = bit_i?219:177;
052 sos_x86_videomem_putchar(row, col++,
053 attribute,
054 ascii_code);
055 }
056 }
057
058
059
060 static void clk_it(int intid,
061 const struct sos_cpu_kstate *cpu_kstate)
062 {
063 static sos_ui32_t clock_count = 0;
064
065 display_bits(0, 48,
066 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
067 clock_count);
068 clock_count++;
069 }
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)
082 {
083 static void backtracer(sos_vaddr_t PC,
084 sos_vaddr_t params,
085 sos_ui32_t depth,
086 void *custom_arg)
087 {
088 sos_ui32_t invalid = 0xffffffff, *arg1, *arg2, *arg3, *arg4;
089
090
091
092
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 }
132
133
134
135 static void pgflt_ex(int intid, const struct sos_cpu_kstate *ctxt)
136 {
137 static sos_ui32_t demand_paging_count = 0;
138 sos_vaddr_t faulting_vaddr = sos_cpu_kstate_get_EX_faulting_vaddr(ctxt);
139 sos_paddr_t ppage_paddr;
140
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
180 }
181
182
183
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)
198 {
199 sos_kfree(stack_vaddr);
200 }
201
202
203 static void exit_hello12(sos_vaddr_t stack_vaddr)
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
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)
449 {
450 }
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 }
455
456
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);
470 }
471
472 data_reader_to_lexer = '\0';
473 sos_cpu_kstate_switch(& st_reader, st_lexer);
474 }
475
476
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;
494
495 static void func_lexer(sos_ui32_t unused)
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) )
529 {
530
531
532 if ( (got_what_before != GOT_SPACE) )
533 sos_cpu_kstate_switch(& st_lexer, st_parser);
534
535 data_lexer_to_parser.number = 0;
536 }
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;
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);
577 }
578
579
580
581
582
583 struct syntax_node
584 {
585 enum { YY_IS_BINOP, YY_IS_UNAROP, YY_IS_NUM, YY_IS_VAR } type;
586 union
587 {
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 };
602
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();
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)
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 }
661
662
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 }
669
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
795 }
796
797
798
799
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
830
831 struct func_eval_params
832 {
833 const struct syntax_node *e;
834 const char **var_name;
835 int *var_val;
836 int nb_vars;
837
838 int result;
839 };
840
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)
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;
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);
978 }
979
980
981
982
983
984 void sos_main(unsigned long magic, unsigned long addr)
985 {
986 unsigned i;
987 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
988 struct syntax_node *syntax_tree;
989
990
991
992
993 multiboot_info_t *mbi;
994 mbi = (multiboot_info_t *) addr;
995
996
997 sos_bochs_setup();
998
999 sos_x86_videomem_setup();
1000 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
1001
1002
1003 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
1004
1005 sos_x86_videomem_printf(1, 0,
1006 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
1007 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
1008 "SOS", ',',
1009 (unsigned)(mbi->mem_upper >> 10) + 1,
1010 (unsigned)mbi->mem_upper);
1011 else
1012
1013 sos_x86_videomem_printf(1, 0,
1014 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
1015 "Welcome to SOS");
1016
1017 sos_bochs_putstring("Message in a bochs\n");
1018
1019
1020 sos_gdt_subsystem_setup();
1021 sos_idt_subsystem_setup();
1022
1023
1024 sos_exception_subsystem_setup();
1025 sos_irq_subsystem_setup();
1026
1027
1028 sos_i8254_set_frequency(100);
1029
1030
1031 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
1032 {
1033 sos_x86_videomem_putstring(20, 0,
1034 SOS_X86_VIDEO_FG_LTRED
1035 | SOS_X86_VIDEO_BG_BLUE
1036 | SOS_X86_VIDEO_FG_BLINKING,
1037 "I'm not loaded with Grub !");
1038
1039 for (;;)
1040 continue;
1041 }
1042
1043
1044
1045
1046
1047
1048 sos_irq_set_routine(SOS_IRQ_TIMER,
1049 clk_it);
1050
1051
1052
1053
1054
1055
1056
1057
1058 sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
1059 & sos_kernel_core_base_paddr,
1060 & sos_kernel_core_top_paddr);
1061
1062
1063
1064
1065
1066
1067
1068 SOS_ASSERT_FATAL(SOS_OK ==
1069 sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
1070 sos_kernel_core_top_paddr));
1071
1072
1073 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
1074 pgflt_ex);
1075
1076
1077
1078
1079
1080 if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
1081 sos_kernel_core_top_paddr,
1082 bootstrap_stack_bottom,
1083 bootstrap_stack_bottom
1084 + bootstrap_stack_size))
1085 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
1086
1087 if (sos_kmalloc_subsystem_setup())
1088 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
1089
1090
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
1153
1154
1155 for (;;)
1156 {
1157
1158
1159 asm("hlt\n");
1160
1161 continue;
1162 }
1163 }