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>
>> 028 #include <hwcore/paging.h>
>> 029 #include <hwcore/mm_context.h>
>> 030 #include <hwcore/swintr.h>
>> 031 #include <sos/kmem_vmm.h>
>> 032 #include <sos/kmalloc.h>
>> 033 #include <sos/time.h>
>> 034 #include <sos/thread.h>
>> 035 #include <sos/process.h>
029 #include <sos/klibc.h> 036 #include <sos/klibc.h>
030 #include <sos/assert.h> 037 #include <sos/assert.h>
031 #include <drivers/x86_videomem.h> 038 #include <drivers/x86_videomem.h>
032 #include <drivers/bochs.h> 039 #include <drivers/bochs.h>
>> 040 #include <sos/calcload.h>
033 041
034 042
035 043
036 044
037 static void display_bits(unsigned char row, un !! 045 void display_bits(unsigned char row, unsigned char col,
038 unsigned char attribu !! 046 unsigned char attribute,
039 sos_ui32_t integer) !! 047 sos_ui32_t integer)
040 { 048 {
041 int i; 049 int i;
042 050
043 for (i = 31 ; i >= 0 ; i--) 051 for (i = 31 ; i >= 0 ; i--)
044 { 052 {
045 053
046 int bit_i = (integer & (1 << i)); 054 int bit_i = (integer & (1 << i));
047 055
048 unsigned char ascii_code = bit_i?219:177 056 unsigned char ascii_code = bit_i?219:177;
049 sos_x86_videomem_putchar(row, col++, 057 sos_x86_videomem_putchar(row, col++,
050 attribute, 058 attribute,
051 ascii_code); 059 ascii_code);
052 } 060 }
053 } 061 }
054 062
055 063
056 064
057 static void clk_it(int intid) 065 static void clk_it(int intid)
058 { 066 {
059 static sos_ui32_t clock_count = 0; 067 static sos_ui32_t clock_count = 0;
060 068
061 display_bits(0, 48, 069 display_bits(0, 48,
062 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 070 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
063 clock_count); 071 clock_count);
064 clock_count++; 072 clock_count++;
065 073
>> 074
>> 075 sos_time_do_tick();
>> 076
>> 077
>> 078 sos_sched_do_timer_tick();
066 } 079 }
067 080
068 #define MY_PPAGE_NUM_INT 511 !! 081
069 struct my_ppage !! 082
>> 083
>> 084
>> 085
>> 086
>> 087
>> 088 static void pgflt_ex(int intid, struct sos_cpu_state *ctxt)
070 { 089 {
071 sos_ui32_t before[MY_PPAGE_NUM_INT]; !! 090 static sos_ui32_t demand_paging_count = 0;
072 struct my_ppage *prev, *next; !! 091 sos_vaddr_t faulting_vaddr = sos_cpu_context_get_EX_faulting_vaddr(ctxt);
073 sos_ui32_t after[MY_PPAGE_NUM_INT]; !! 092 sos_paddr_t ppage_paddr;
074 }; !! 093
075 !! 094 if (sos_cpu_context_is_in_user_mode(ctxt))
076 static void test_physmem() <<
077 { <<
078 <<
079 struct my_ppage *ppage_list, *my_ppage; <<
080 sos_count_t num_alloc_ppages = 0, num_free_p <<
081 <<
082 ppage_list = NULL; <<
083 while ((my_ppage = (struct my_ppage*)sos_phy <<
084 != NULL) <<
085 { 095 {
086 int i; !! 096
087 num_alloc_ppages++; !! 097
088 !! 098 sos_bochs_printf("Unresolved USER page Fault at instruction 0x%x on access to address 0x%x (info=%x)!\n",
089 !! 099 sos_cpu_context_get_PC(ctxt),
090 sos_x86_videomem_printf(2, 0, !! 100 (unsigned)faulting_vaddr,
091 SOS_X86_VIDEO_FG !! 101 (unsigned)sos_cpu_context_get_EX_info(ctxt));
092 | SOS_X86_VIDEO_ !! 102 sos_bochs_printf("Terminating User thread\n");
093 "Could allocate !! 103 sos_thread_exit();
094 num_alloc_ppages !! 104 }
095 !! 105
096 !! 106
097 for (i = 0 ; i < MY_PPAGE_NUM_INT ; i++) !! 107 if (! sos_kmem_vmm_is_valid_vaddr(faulting_vaddr))
098 my_ppage->before[i] = my_ppage->after[ !! 108 {
099 !! 109
100 !! 110
101 list_add_tail(ppage_list, my_ppage); !! 111 sos_display_fatal_error("Unresolved page Fault at instruction 0x%x on access to address 0x%x (info=%x)!",
102 } !! 112 sos_cpu_context_get_PC(ctxt),
103 !! 113 (unsigned)faulting_vaddr,
104 !! 114 (unsigned)sos_cpu_context_get_EX_info(ctxt));
105 while ((my_ppage = list_pop_head(ppage_list) !! 115 SOS_ASSERT_FATAL(! "Got page fault (note: demand paging is disabled)");
106 { !! 116 }
107 !! 117
108 !! 118
109 int i; !! 119
110 for (i = 0 ; i < MY_PPAGE_NUM_INT ; i++) !! 120
>> 121
>> 122
>> 123
>> 124 demand_paging_count ++;
>> 125 display_bits(0, 0,
>> 126 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
>> 127 demand_paging_count);
>> 128
>> 129
>> 130 ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
>> 131 if (! ppage_paddr)
>> 132 SOS_ASSERT_FATAL(! "TODO: implement swap. (Out of mem in demand paging because no swap for kernel yet !)");
>> 133 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(ppage_paddr,
>> 134 SOS_PAGE_ALIGN_INF(faulting_vaddr),
>> 135 FALSE,
>> 136 SOS_VM_MAP_PROT_READ
>> 137 | SOS_VM_MAP_PROT_WRITE
>> 138 | SOS_VM_MAP_ATOMIC));
>> 139 sos_physmem_unref_physpage(ppage_paddr);
>> 140
>> 141
>> 142 }
>> 143
>> 144
>> 145
>> 146
>> 147
>> 148
>> 149
>> 150
>> 151
>> 152 struct thr_arg
>> 153 {
>> 154 char character;
>> 155 int color;
>> 156
>> 157 int col;
>> 158 int row;
>> 159 };
>> 160
>> 161
>> 162 static void demo_thread(void *arg)
>> 163 {
>> 164 struct thr_arg *thr_arg = (struct thr_arg*)arg;
>> 165 int progress = 0;
>> 166
>> 167 sos_bochs_printf("start %c", thr_arg->character);
>> 168 while (1)
>> 169 {
>> 170 progress ++;
>> 171 display_bits(thr_arg->row, thr_arg->col+1, thr_arg->color, progress);
>> 172
>> 173 sos_bochs_putchar(thr_arg->character);
>> 174
>> 175
>> 176 if ((random() % 100) == 0)
111 { 177 {
112 !! 178 sos_bochs_printf("[37myield(%c)[m\n", thr_arg->character);
113 if ((my_ppage->before[i] != (sos_ui !! 179 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'Y');
114 || (my_ppage->after[i] != (sos_ !! 180 SOS_ASSERT_FATAL(SOS_OK == sos_thread_yield());
115 { !! 181 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
116 <<
117 sos_x86_videomem_putstring(20, 0 <<
118 SOS_X <<
119 | S <<
120 "Page <<
121 return; <<
122 } <<
123 } 182 }
124 183
125 !! 184
126 if (sos_physmem_unref_physpage((sos_padd !! 185 else if ((random() % 200) == 0)
127 { 186 {
128 !! 187 struct sos_time t = (struct sos_time){ .sec=0, .nanosec=50000000 };
129 sos_x86_videomem_putstring(20, 0, !! 188 sos_bochs_printf("[37msleep1(%c)[m\n", thr_arg->character);
130 SOS_X86_V !! 189 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 's');
131 | SOS_X !! 190 SOS_ASSERT_FATAL(SOS_OK == sos_thread_sleep(& t));
132 "Cannot r !! 191 SOS_ASSERT_FATAL(sos_time_is_zero(& t));
133 return; !! 192 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
134 } 193 }
135 194
136 !! 195
137 num_free_ppages ++; !! 196 else if ((random() % 300) == 0)
138 sos_x86_videomem_printf(2, 0, !! 197 {
139 SOS_X86_VIDEO_FG !! 198 struct sos_time t = (struct sos_time){ .sec=0, .nanosec=300000000 };
140 | SOS_X86_VIDEO_ !! 199 sos_bochs_printf("[37msleep2(%c)[m\n", thr_arg->character);
141 "Could free %d p !! 200 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'S');
142 num_free_ppages) !! 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');
>> 204 }
>> 205
>> 206
>> 207 }
>> 208 }
>> 209
>> 210
>> 211 static void test_thread()
>> 212 {
>> 213
>> 214
>> 215 static struct thr_arg arg_b, arg_c, arg_d, arg_e, arg_R, arg_S;
>> 216 sos_ui32_t flags;
>> 217
>> 218 sos_disable_IRQs(flags);
>> 219
>> 220 arg_b = (struct thr_arg) { .character='b', .col=0, .row=21, .color=0x14 };
>> 221 sos_create_kernel_thread("YO[b]", demo_thread, (void*)&arg_b, SOS_SCHED_PRIO_TS_LOWEST);
>> 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);
>> 225
>> 226 arg_d = (struct thr_arg) { .character='d', .col=0, .row=20, .color=0x14 };
>> 227 sos_create_kernel_thread("YO[d]", demo_thread, (void*)&arg_d, SOS_SCHED_PRIO_TS_LOWEST-1);
>> 228
>> 229 arg_e = (struct thr_arg) { .character='e', .col=0, .row=19, .color=0x14 };
>> 230 sos_create_kernel_thread("YO[e]", demo_thread, (void*)&arg_e, SOS_SCHED_PRIO_TS_LOWEST-2);
>> 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);
>> 234
>> 235 arg_S = (struct thr_arg) { .character='S', .col=0, .row=16, .color=0x1c };
>> 236 sos_create_kernel_thread("YO[S]", demo_thread, (void*)&arg_S, SOS_SCHED_PRIO_RT_LOWEST-1);
>> 237
>> 238 sos_restore_IRQs(flags);
>> 239 }
>> 240
>> 241
>> 242
>> 243
>> 244
>> 245
>> 246 static void idle_thread()
>> 247 {
>> 248 sos_ui32_t idle_twiddle = 0;
>> 249
>> 250 while (1)
>> 251 {
>> 252
>> 253
>> 254 asm("hlt\n");
>> 255
>> 256 idle_twiddle ++;
>> 257 display_bits(0, 0, SOS_X86_VIDEO_FG_GREEN | SOS_X86_VIDEO_BG_BLUE,
>> 258 idle_twiddle);
>> 259
>> 260
>> 261 sos_thread_yield();
143 } 262 }
>> 263 }
144 264
145 <<
146 sos_x86_videomem_printf(2, 0, <<
147 SOS_X86_VIDEO_FG_LTG <<
148 | SOS_X86_VIDEO_BG_B <<
149 "Could allocate %d b <<
150 num_alloc_ppages << <<
151 num_free_ppages << S <<
152 265
153 SOS_ASSERT_FATAL(num_alloc_ppages == num_fre !! 266
>> 267
>> 268
>> 269 static void stat_thread()
>> 270 {
>> 271 while (1)
>> 272 {
>> 273 sos_ui32_t flags;
>> 274 sos_ui32_t load1, load5, load15;
>> 275 char str1[11], str5[11], str15[11];
>> 276 struct sos_time t;
>> 277 t.sec = 1;
>> 278 t.nanosec = 0;
>> 279
>> 280 sos_thread_sleep(& t);
>> 281
>> 282 sos_disable_IRQs(flags);
>> 283
>> 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);
>> 322 }
154 } 323 }
155 324
156 325
157 !! 326
>> 327
>> 328
158 void sos_main(unsigned long magic, unsigned lo 329 void sos_main(unsigned long magic, unsigned long addr)
159 { 330 {
160 unsigned i; 331 unsigned i;
161 sos_paddr_t sos_kernel_core_base_paddr, sos_ 332 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
>> 333 struct sos_time tick_resolution;
162 334
163 335
164 336
165 337
166 multiboot_info_t *mbi; 338 multiboot_info_t *mbi;
167 mbi = (multiboot_info_t *) addr; 339 mbi = (multiboot_info_t *) addr;
168 340
169 341
170 sos_bochs_setup(); 342 sos_bochs_setup();
171 343
172 sos_x86_videomem_setup(); 344 sos_x86_videomem_setup();
173 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 345 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
174 346
175 347
176 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 348 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
177 349
178 sos_x86_videomem_printf(1, 0, 350 sos_x86_videomem_printf(1, 0,
179 SOS_X86_VIDEO_FG_Y 351 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
180 "Welcome From GRUB 352 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
181 "SOS", ',', !! 353 "SOS article 7", ',',
182 (unsigned)(mbi->me 354 (unsigned)(mbi->mem_upper >> 10) + 1,
183 (unsigned)mbi->mem 355 (unsigned)mbi->mem_upper);
184 else 356 else
185 357
186 sos_x86_videomem_printf(1, 0, 358 sos_x86_videomem_printf(1, 0,
187 SOS_X86_VIDEO_FG_Y 359 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
188 "Welcome to SOS"); !! 360 "Welcome to SOS article 7");
189 361
190 sos_bochs_putstring("Message in a bochs\n"); !! 362 sos_bochs_putstring("Message in a bochs: This is SOS article 7.\n");
191 363
192 364
193 sos_gdt_setup(); !! 365 sos_gdt_subsystem_setup();
194 sos_idt_setup(); !! 366 sos_idt_subsystem_setup();
195 367
196 368
197 sos_exceptions_setup(); !! 369 sos_exception_subsystem_setup();
198 sos_irq_setup(); !! 370 sos_irq_subsystem_setup();
199 371
200 372
201 sos_i8254_set_frequency(100); 373 sos_i8254_set_frequency(100);
202 374
>> 375
>> 376
>> 377 tick_resolution = (struct sos_time) { .sec=0, .nanosec=10000000UL };
>> 378 sos_time_subsysem_setup(& tick_resolution);
203 379
204 380
205 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 381 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
206 { 382 {
207 sos_x86_videomem_putstring(20, 0, 383 sos_x86_videomem_putstring(20, 0,
208 SOS_X86_VIDEO 384 SOS_X86_VIDEO_FG_LTRED
209 | SOS_X86_V 385 | SOS_X86_VIDEO_BG_BLUE
210 | SOS_X86_V 386 | SOS_X86_VIDEO_FG_BLINKING,
211 "I'm not load 387 "I'm not loaded with Grub !");
212 388
213 for (;;) 389 for (;;)
214 continue; 390 continue;
215 } 391 }
216 392
>> 393
>> 394
>> 395
>> 396
217 397
218 sos_irq_set_routine(SOS_IRQ_TIMER, 398 sos_irq_set_routine(SOS_IRQ_TIMER,
219 clk_it); !! 399 clk_it);
220 !! 400
221 !! 401
222 asm volatile ("sti\n"); !! 402
>> 403
>> 404
223 405
224 406
225 407
226 sos_physmem_setup((mbi->mem_upper<<10) + (1< !! 408 sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
227 & sos_kernel_core_base_pad !! 409 & sos_kernel_core_base_paddr,
228 & sos_kernel_core_top_padd !! 410 & sos_kernel_core_top_paddr);
229 test_physmem(); !! 411
230 !! 412
231 !! 413
232 for (;;) !! 414
233 continue; !! 415
>> 416
>> 417
>> 418 SOS_ASSERT_FATAL(SOS_OK ==
>> 419 sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
>> 420 sos_kernel_core_top_paddr));
>> 421
>> 422
>> 423 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
>> 424 pgflt_ex);
>> 425
>> 426
>> 427
>> 428
>> 429
>> 430 if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
>> 431 sos_kernel_core_top_paddr,
>> 432 bootstrap_stack_bottom,
>> 433 bootstrap_stack_bottom
>> 434 + bootstrap_stack_size))
>> 435 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
>> 436
>> 437 if (sos_kmalloc_subsystem_setup())
>> 438 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
>> 439
>> 440
>> 441
>> 442
>> 443 sos_mm_context_subsystem_setup();
>> 444
>> 445
>> 446
>> 447
>> 448 sos_cpu_context_subsystem_setup();
>> 449
>> 450
>> 451
>> 452
>> 453 sos_swintr_subsystem_setup();
>> 454
>> 455
>> 456
>> 457
>> 458
>> 459
>> 460
>> 461 sos_thread_subsystem_setup(bootstrap_stack_bottom,
>> 462 bootstrap_stack_size);
>> 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);
>> 478
>> 479
>> 480
>> 481
>> 482
>> 483 sos_process_subsystem_setup();
>> 484
>> 485
>> 486
>> 487
>> 488 asm volatile ("sti\n");
234 489
235 return; !! 490
>> 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 !");
236 } 514 }