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