Diff markup
001 001
>> 002
002 003
003 004
004 005
005 006
006 007
007 008
008 009
009 010
010 011
011 012
012 013
013 014
014 015
015 016
016 017
017 018
018 019
019 020
020 #include <bootstrap/multiboot.h> 021 #include <bootstrap/multiboot.h>
021 #include <hwcore/idt.h> 022 #include <hwcore/idt.h>
022 #include <hwcore/gdt.h> 023 #include <hwcore/gdt.h>
023 #include <hwcore/irq.h> 024 #include <hwcore/irq.h>
024 #include <hwcore/exception.h> 025 #include <hwcore/exception.h>
025 #include <hwcore/i8254.h> 026 #include <hwcore/i8254.h>
026 #include <sos/list.h> 027 #include <sos/list.h>
027 #include <sos/physmem.h> 028 #include <sos/physmem.h>
028 #include <hwcore/paging.h> 029 #include <hwcore/paging.h>
029 #include <sos/kmem_vmm.h> 030 #include <sos/kmem_vmm.h>
030 #include <sos/kmalloc.h> 031 #include <sos/kmalloc.h>
031 #include <sos/time.h> <<
032 #include <sos/thread.h> <<
033 #include <sos/klibc.h> 032 #include <sos/klibc.h>
034 #include <sos/assert.h> 033 #include <sos/assert.h>
035 #include <drivers/x86_videomem.h> 034 #include <drivers/x86_videomem.h>
036 #include <drivers/bochs.h> 035 #include <drivers/bochs.h>
037 036
038 037
039 038
040 039
041 void display_bits(unsigned char row, unsigned !! 040 static void display_bits(unsigned char row, unsigned char col,
042 unsigned char attribute, !! 041 unsigned char attribute,
043 sos_ui32_t integer) !! 042 sos_ui32_t integer)
044 { 043 {
045 int i; 044 int i;
046 045
047 for (i = 31 ; i >= 0 ; i--) 046 for (i = 31 ; i >= 0 ; i--)
048 { 047 {
049 048
050 int bit_i = (integer & (1 << i)); 049 int bit_i = (integer & (1 << i));
051 050
052 unsigned char ascii_code = bit_i?219:177 051 unsigned char ascii_code = bit_i?219:177;
053 sos_x86_videomem_putchar(row, col++, 052 sos_x86_videomem_putchar(row, col++,
054 attribute, 053 attribute,
055 ascii_code); 054 ascii_code);
056 } 055 }
057 } 056 }
058 057
059 058
060 059
061 static void clk_it(int intid) 060 static void clk_it(int intid)
062 { 061 {
063 static sos_ui32_t clock_count = 0; 062 static sos_ui32_t clock_count = 0;
064 063
065 display_bits(0, 48, 064 display_bits(0, 48,
066 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 065 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
067 clock_count); 066 clock_count);
068 clock_count++; 067 clock_count++;
069 068
070 <<
071 sos_time_do_tick(); <<
072 } 069 }
>> 070 struct digit
>> 071 {
>> 072 struct digit *prev, *next;
>> 073 char value;
>> 074 };
073 075
>> 076
>> 077
>> 078
>> 079 typedef struct digit * big_number_t;
074 080
075 <<
076 <<
077 <<
078 <<
079 <<
080 static void dump_backtrace(const struct sos_cp <<
081 sos_vaddr_t stack_b <<
082 sos_size_t stack_s <<
083 sos_bool_t on_conso <<
084 sos_bool_t on_bochs <<
085 { <<
086 static void backtracer(sos_vaddr_t PC, <<
087 sos_vaddr_t params, <<
088 sos_ui32_t depth, <<
089 void *custom_arg) <<
090 { <<
091 sos_ui32_t invalid = 0xffffffff, *arg1, <<
092 <<
093 <<
094 <<
095 <<
096 <<
097 arg1 = (sos_ui32_t*)params; <<
098 arg2 = (sos_ui32_t*)(params+4); <<
099 arg3 = (sos_ui32_t*)(params+8); <<
100 arg4 = (sos_ui32_t*)(params+12); <<
101 <<
102 <<
103 <<
104 #define INTERVAL_OK(b,v,u) ( ((b) <= (sos_vadd <<
105 && ((sos_vaddr_t) <<
106 if (!INTERVAL_OK(stack_bottom, arg1, sta <<
107 arg1 = &invalid; <<
108 if (!INTERVAL_OK(stack_bottom, arg2, sta <<
109 arg2 = &invalid; <<
110 if (!INTERVAL_OK(stack_bottom, arg3, sta <<
111 arg3 = &invalid; <<
112 if (!INTERVAL_OK(stack_bottom, arg4, sta <<
113 arg4 = &invalid; <<
114 <<
115 <<
116 if (on_bochs) <<
117 sos_bochs_printf("[%d] PC=0x%x arg1=0x <<
118 (unsigned)depth, (uns <<
119 (unsigned)*arg1, (uns <<
120 (unsigned)*arg3); <<
121 <<
122 if (on_console) <<
123 sos_x86_videomem_printf(23-depth, 3, <<
124 SOS_X86_VIDEO_ <<
125 | SOS_X86_VI <<
126 "[%d] PC=0x%x <<
127 (unsigned)dept <<
128 (unsigned)*arg <<
129 (unsigned)*arg <<
130 <<
131 } <<
132 <<
133 sos_backtrace(cpu_state, 15, stack_bottom, s <<
134 } <<
135 <<
136 <<
137 <<
138 static void pgflt_ex(int intid, const struct s <<
139 { <<
140 static sos_ui32_t demand_paging_count = 0; <<
141 sos_vaddr_t faulting_vaddr = sos_cpu_context <<
142 sos_paddr_t ppage_paddr; <<
143 <<
144 <<
145 if (! sos_kmem_vmm_is_valid_vaddr(faulting_v <<
146 { <<
147 <<
148 <<
149 dump_backtrace(ctxt, <<
150 bootstrap_stack_bottom, <<
151 bootstrap_stack_size, <<
152 TRUE, TRUE); <<
153 sos_display_fatal_error("Unresolved page <<
154 sos_cpu_context_ <<
155 (unsigned)faulti <<
156 (unsigned)sos_cp <<
157 SOS_ASSERT_FATAL(! "Got page fault (note <<
158 } <<
159 081
>> 082
>> 083 void bn_push_lsd(big_number_t * bn, char value)
>> 084 {
>> 085 struct digit *d;
>> 086 d = (struct digit*) sos_kmalloc(sizeof(struct digit), 0);
>> 087 SOS_ASSERT_FATAL(d != NULL);
>> 088 d->value = value;
>> 089 list_add_tail(*bn, d);
>> 090 }
160 091
161 !! 092
162 !! 093
163 !! 094 void bn_push_msd(big_number_t * bn, char value)
164 !! 095 {
165 !! 096 struct digit *d;
166 demand_paging_count ++; !! 097 d = (struct digit*) sos_kmalloc(sizeof(struct digit), 0);
167 display_bits(0, 0, !! 098 SOS_ASSERT_FATAL(d != NULL);
168 SOS_X86_VIDEO_FG_LTRED | SOS_X8 !! 099 d->value = value;
169 demand_paging_count); !! 100 list_add_head(*bn, d);
170 <<
171 <<
172 ppage_paddr = sos_physmem_ref_physpage_new(F <<
173 if (! ppage_paddr) <<
174 SOS_ASSERT_FATAL(! "TODO: implement swap. <<
175 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(pp <<
176 SO <<
177 FA <<
178 SO <<
179 | <<
180 | <<
181 sos_physmem_unref_physpage(ppage_paddr); <<
182 <<
183 <<
184 } 101 }
185 102
186 103
187 !! 104
188 !! 105 big_number_t bn_new(unsigned long int i)
189 !! 106 {
190 !! 107 big_number_t retval;
191 !! 108
192 !! 109 list_init(retval);
>> 110 do
>> 111 {
>> 112 bn_push_msd(&retval, i%10);
>> 113 i /= 10;
>> 114 }
>> 115 while (i != 0);
>> 116
>> 117 return retval;
>> 118 }
>> 119
193 120
194 struct thr_arg !! 121
>> 122 big_number_t bn_copy(const big_number_t bn)
195 { 123 {
196 char character; !! 124 big_number_t retval;
197 int color; !! 125 int nb_elts;
>> 126 struct digit *d;
198 127
199 int col; !! 128 list_init(retval);
200 int row; !! 129 list_foreach(bn, d, nb_elts)
201 }; !! 130 {
>> 131 bn_push_lsd(&retval, d->value);
>> 132 }
202 133
>> 134 return retval;
>> 135 }
203 136
204 static void demo_thread(void *arg) !! 137
>> 138
>> 139 void bn_del(big_number_t * bn)
205 { 140 {
206 struct thr_arg *thr_arg = (struct thr_arg*)a !! 141 struct digit *d;
207 int progress = 0; <<
208 142
209 sos_bochs_printf("start %c", thr_arg->charac !! 143 list_collapse(*bn, d)
210 while (1) <<
211 { 144 {
212 progress ++; !! 145 sos_kfree((sos_vaddr_t)d);
213 display_bits(thr_arg->row, thr_arg->col+ !! 146 }
>> 147 }
214 148
215 sos_bochs_putchar(thr_arg->character); <<
216 149
217 !! 150
218 if ((random() % 100) == 0) !! 151 void bn_shift(big_number_t *bn, int shift)
219 { !! 152 {
220 sos_bochs_printf("[37myield(%c)[m\ !! 153 for ( ; shift > 0 ; shift --)
221 sos_x86_videomem_putchar(thr_arg->ro !! 154 {
222 SOS_ASSERT_FATAL(SOS_OK == sos_threa !! 155 bn_push_lsd(bn, 0);
223 sos_x86_videomem_putchar(thr_arg->ro !! 156 }
224 } !! 157 }
225 158
226 <<
227 else if ((random() % 200) == 0) <<
228 { <<
229 struct sos_time t = (struct sos_time <<
230 sos_bochs_printf("[37msleep1(%c)[m <<
231 sos_x86_videomem_putchar(thr_arg->ro <<
232 SOS_ASSERT_FATAL(SOS_OK == sos_threa <<
233 SOS_ASSERT_FATAL(sos_time_is_zero(& <<
234 sos_x86_videomem_putchar(thr_arg->ro <<
235 } <<
236 159
237 !! 160
238 else if ((random() % 300) == 0) !! 161 void bn_print_bochs(const big_number_t bn)
>> 162 {
>> 163 int nb_elts;
>> 164 const struct digit *d;
>> 165
>> 166 if (list_is_empty(bn))
>> 167 sos_bochs_printf("0");
>> 168 else
>> 169 list_foreach(bn, d, nb_elts)
>> 170 sos_bochs_printf("%d", d->value);
>> 171 }
>> 172
>> 173
>> 174 void bn_print_console(unsigned char row, unsigned char col,
>> 175 unsigned char attribute,
>> 176 const big_number_t bn,
>> 177 int nb_decimals)
>> 178 {
>> 179 if (list_is_empty(bn))
>> 180 sos_x86_videomem_printf(row, col, attribute, "0");
>> 181 else
>> 182 {
>> 183 int nb_elts;
>> 184 const struct digit *d;
>> 185 unsigned char x = col;
>> 186
>> 187 list_foreach(bn, d, nb_elts)
239 { 188 {
240 struct sos_time t = (struct sos_time !! 189 if (nb_elts == 0)
241 sos_bochs_printf("[37msleep2(%c)[m !! 190 {
242 sos_x86_videomem_putchar(thr_arg->ro !! 191 sos_x86_videomem_printf(row, x, attribute, "%d.", d->value);
243 SOS_ASSERT_FATAL(SOS_OK == sos_threa !! 192 x += 2;
244 SOS_ASSERT_FATAL(sos_time_is_zero(& !! 193 }
245 sos_x86_videomem_putchar(thr_arg->ro !! 194 else if (nb_elts < nb_decimals)
>> 195 {
>> 196 sos_x86_videomem_printf(row, x, attribute, "%d", d->value);
>> 197 x ++;
>> 198 }
246 } 199 }
247 200
248 !! 201 sos_x86_videomem_printf(row, x, attribute, " . 10^{%d} ", nb_elts-1);
249 } 202 }
250 } 203 }
251 204
252 205
253 static void test_thread() !! 206
>> 207 big_number_t bn_add (const big_number_t bn1, const big_number_t bn2)
254 { 208 {
255 !! 209 big_number_t retval;
256 !! 210 const struct digit *d1, *d2;
257 static struct thr_arg arg_b, arg_c, arg_d, a !! 211 sos_bool_t bn1_end = FALSE, bn2_end = FALSE;
258 sos_ui32_t flags; !! 212 char carry = 0;
259 !! 213
260 sos_disable_IRQs(flags); !! 214 list_init(retval);
>> 215 d1 = list_get_tail(bn1);
>> 216 bn1_end = list_is_empty(bn1);
>> 217 d2 = list_get_tail(bn2);
>> 218 bn2_end = list_is_empty(bn2);
>> 219 do
>> 220 {
>> 221 if (! bn1_end)
>> 222 carry += d1->value;
>> 223 if (! bn2_end)
>> 224 carry += d2->value;
>> 225
>> 226 bn_push_msd(&retval, carry % 10);
>> 227 carry /= 10;
>> 228
>> 229 if (! bn1_end)
>> 230 d1 = d1->prev;
>> 231 if (! bn2_end)
>> 232 d2 = d2->prev;
>> 233 if (d1 == list_get_tail(bn1))
>> 234 bn1_end = TRUE;
>> 235 if (d2 == list_get_tail(bn2))
>> 236 bn2_end = TRUE;
>> 237 }
>> 238 while (!bn1_end || !bn2_end);
261 239
262 arg_b = (struct thr_arg) { .character='b', . !! 240 if (carry > 0)
263 sos_create_kernel_thread("YO[b]", demo_threa !! 241 {
>> 242 bn_push_msd(&retval, carry);
>> 243 }
264 244
265 arg_c = (struct thr_arg) { .character='c', . !! 245 return retval;
266 sos_create_kernel_thread("YO[c]", demo_threa !! 246 }
267 247
268 arg_d = (struct thr_arg) { .character='d', . <<
269 sos_create_kernel_thread("YO[d]", demo_threa <<
270 248
271 arg_e = (struct thr_arg) { .character='e', . !! 249
272 sos_create_kernel_thread("YO[e]", demo_threa !! 250 big_number_t bn_muli (const big_number_t bn, char digit)
>> 251 {
>> 252 big_number_t retval;
>> 253 int nb_elts;
>> 254 char carry = 0;
>> 255 const struct digit *d;
273 256
274 arg_R = (struct thr_arg) { .character='R', . !! 257 list_init(retval);
275 sos_create_kernel_thread("YO[R]", demo_threa !! 258 list_foreach_backward(bn, d, nb_elts)
>> 259 {
>> 260 carry += d->value * digit;
>> 261 bn_push_msd(&retval, carry % 10);
>> 262 carry /= 10;
>> 263 }
276 264
277 arg_S = (struct thr_arg) { .character='S', . !! 265 if (carry > 0)
278 sos_create_kernel_thread("YO[S]", demo_threa !! 266 {
>> 267 bn_push_msd(&retval, carry);
>> 268 }
279 269
280 sos_restore_IRQs(flags); !! 270 return retval;
281 } 271 }
282 272
283 273
284 !! 274
285 !! 275 big_number_t bn_mult(const big_number_t bn1, const big_number_t bn2)
286 <<
287 <<
288 static void idle_thread() <<
289 { 276 {
290 sos_ui32_t idle_twiddle = 0; !! 277 int shift = 0;
>> 278 big_number_t retval;
>> 279 int nb_elts;
>> 280 struct digit *d;
291 281
292 while (1) !! 282 list_init(retval);
>> 283 list_foreach_backward(bn2, d, nb_elts)
293 { 284 {
294 !! 285 big_number_t retmult = bn_muli(bn1, d->value);
295 !! 286 big_number_t old_retval = retval;
296 asm("hlt\n"); !! 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
>> 294 return retval;
>> 295 }
297 296
298 idle_twiddle ++; !! 297
299 display_bits(0, 0, SOS_X86_VIDEO_FG_GREE !! 298
300 idle_twiddle); !! 299 big_number_t bn_fact(unsigned long int v)
301 !! 300 {
302 !! 301 unsigned long int i;
303 sos_thread_yield(); !! 302 big_number_t retval = bn_new(1);
>> 303 for (i = 1 ; i <= v ; i++)
>> 304 {
>> 305 big_number_t I = bn_new(i);
>> 306 big_number_t tmp = bn_mult(retval, I);
>> 307 sos_x86_videomem_printf(4, 0,
>> 308 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_LTGREEN,
>> 309 "%d! = ", (int)i);
>> 310 bn_print_console(4, 8, SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_WHITE,
>> 311 tmp, 55);
>> 312 bn_del(& I);
>> 313 bn_del(& retval);
>> 314 retval = tmp;
304 } 315 }
>> 316
>> 317 return retval;
305 } 318 }
306 319
307 320
308 !! 321 void bn_test()
309 !! 322 {
310 !! 323 big_number_t bn = bn_fact(1000);
>> 324 sos_bochs_printf("1000! = ");
>> 325 bn_print_bochs(bn);
>> 326 sos_bochs_printf("\n");
>> 327
>> 328 }
>> 329
>> 330
>> 331
311 void sos_main(unsigned long magic, unsigned lo 332 void sos_main(unsigned long magic, unsigned long addr)
312 { 333 {
313 unsigned i; 334 unsigned i;
314 sos_paddr_t sos_kernel_core_base_paddr, sos_ 335 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
315 struct sos_time tick_resolution; <<
316 336
317 337
318 338
319 339
320 multiboot_info_t *mbi; 340 multiboot_info_t *mbi;
321 mbi = (multiboot_info_t *) addr; 341 mbi = (multiboot_info_t *) addr;
322 342
323 343
324 sos_bochs_setup(); 344 sos_bochs_setup();
325 345
326 sos_x86_videomem_setup(); 346 sos_x86_videomem_setup();
327 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 347 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
328 348
329 349
330 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 350 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
331 351
332 sos_x86_videomem_printf(1, 0, 352 sos_x86_videomem_printf(1, 0,
333 SOS_X86_VIDEO_FG_Y 353 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
334 "Welcome From GRUB 354 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
335 "SOS article 6.5", !! 355 "SOS", ',',
336 (unsigned)(mbi->me 356 (unsigned)(mbi->mem_upper >> 10) + 1,
337 (unsigned)mbi->mem 357 (unsigned)mbi->mem_upper);
338 else 358 else
339 359
340 sos_x86_videomem_printf(1, 0, 360 sos_x86_videomem_printf(1, 0,
341 SOS_X86_VIDEO_FG_Y 361 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
342 "Welcome to SOS ar !! 362 "Welcome to SOS");
343 363
344 sos_bochs_putstring("Message in a bochs: Thi !! 364 sos_bochs_putstring("Message in a bochs\n");
345 365
346 366
347 sos_gdt_subsystem_setup(); !! 367 sos_gdt_setup();
348 sos_idt_subsystem_setup(); !! 368 sos_idt_setup();
349 369
350 370
351 sos_exception_subsystem_setup(); !! 371 sos_exceptions_setup();
352 sos_irq_subsystem_setup(); !! 372 sos_irq_setup();
353 373
354 374
355 sos_i8254_set_frequency(100); 375 sos_i8254_set_frequency(100);
356 376
357 <<
358 <<
359 tick_resolution = (struct sos_time) { .sec=0 <<
360 sos_time_subsysem_setup(& tick_resolution); <<
361 377
362 378
363 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 379 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
364 { 380 {
365 sos_x86_videomem_putstring(20, 0, 381 sos_x86_videomem_putstring(20, 0,
366 SOS_X86_VIDEO 382 SOS_X86_VIDEO_FG_LTRED
367 | SOS_X86_V 383 | SOS_X86_VIDEO_BG_BLUE
368 | SOS_X86_V 384 | SOS_X86_VIDEO_FG_BLINKING,
369 "I'm not load 385 "I'm not loaded with Grub !");
370 386
371 for (;;) 387 for (;;)
372 continue; 388 continue;
373 } 389 }
374 390
375 <<
376 <<
377 <<
378 <<
379 391
380 sos_irq_set_routine(SOS_IRQ_TIMER, 392 sos_irq_set_routine(SOS_IRQ_TIMER,
381 clk_it); !! 393 clk_it);
382 !! 394
383 !! 395
384 !! 396 asm volatile ("sti\n");
385 <<
386 <<
387 397
388 398
389 399
390 sos_physmem_subsystem_setup((mbi->mem_upper< !! 400 sos_physmem_setup((mbi->mem_upper<<10) + (1<<20),
391 & sos_kernel_cor !! 401 & sos_kernel_core_base_paddr,
392 & sos_kernel_cor !! 402 & sos_kernel_core_top_paddr);
393 403
394 404
395 405
396 406
397 407
398 408
399 409
400 SOS_ASSERT_FATAL(SOS_OK == !! 410 if (sos_paging_setup(sos_kernel_core_base_paddr,
401 sos_paging_subsystem_setup( !! 411 sos_kernel_core_top_paddr))
402 !! 412 sos_bochs_printf("Could not setup paged memory mode\n");
403 !! 413 sos_x86_videomem_printf(2, 0,
404 !! 414 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
405 sos_exception_set_routine(SOS_EXCEPT_PAGE_FA !! 415 "Paged-memory mode is activated");
406 pgflt_ex); <<
407 416
408 <<
409 <<
410 <<
411 417
412 if (sos_kmem_vmm_subsystem_setup(sos_kernel_ !! 418 if (sos_kmem_vmm_setup(sos_kernel_core_base_paddr,
413 sos_kernel_ !! 419 sos_kernel_core_top_paddr))
414 bootstrap_s <<
415 bootstrap_s <<
416 + bootstrap <<
417 sos_bochs_printf("Could not setup the Kern 420 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
418 421
419 if (sos_kmalloc_subsystem_setup()) !! 422 if (sos_kmalloc_setup())
420 sos_bochs_printf("Could not setup the Kmal 423 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
421 424
422 !! 425
423 !! 426 bn_test();
424 <<
425 <<
426 <<
427 sos_thread_subsystem_setup(bootstrap_stack_b <<
428 bootstrap_stack_s <<
429 <<
430 <<
431 sos_sched_subsystem_setup(); <<
432 <<
433 <<
434 SOS_ASSERT_FATAL(sos_create_kernel_thread("i <<
435 <<
436 <<
437 <<
438 asm volatile ("sti\n"); <<
439 <<
440 427
441 !! 428
442 extern void MouseSim(); !! 429 for (;;)
443 MouseSim(); !! 430 continue;
444 test_thread(); <<
445 431
446 !! 432 return;
447 <<
448 <<
449 <<
450 <<
451 <<
452 <<
453 <<
454 <<
455 <<
456 <<
457 <<
458 sos_bochs_printf("Bye from primary thread !\ <<
459 sos_thread_exit(); <<
460 SOS_FATAL_ERROR("No trespassing !"); <<
461 } 433 }