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>
030 #include <sos/list.h> !! 029 #include <sos/kmem_vmm.h>
>> 030 #include <sos/kmalloc.h>
>> 031 #include <sos/time.h>
>> 032 #include <sos/thread.h>
031 #include <sos/klibc.h> 033 #include <sos/klibc.h>
032 #include <sos/assert.h> 034 #include <sos/assert.h>
033 #include <drivers/x86_videomem.h> 035 #include <drivers/x86_videomem.h>
034 #include <drivers/bochs.h> 036 #include <drivers/bochs.h>
035 037
036 038
037 039
038 040
039 static void display_bits(unsigned char row, un !! 041 void display_bits(unsigned char row, unsigned char col,
040 unsigned char attribu !! 042 unsigned char attribute,
041 sos_ui32_t integer) !! 043 sos_ui32_t integer)
042 { 044 {
043 int i; 045 int i;
044 046
045 for (i = 31 ; i >= 0 ; i--) 047 for (i = 31 ; i >= 0 ; i--)
046 { 048 {
047 049
048 int bit_i = (integer & (1 << i)); 050 int bit_i = (integer & (1 << i));
049 051
050 unsigned char ascii_code = bit_i?219:177 052 unsigned char ascii_code = bit_i?219:177;
051 sos_x86_videomem_putchar(row, col++, 053 sos_x86_videomem_putchar(row, col++,
052 attribute, 054 attribute,
053 ascii_code); 055 ascii_code);
054 } 056 }
055 } 057 }
056 058
057 059
058 060
059 static void clk_it(int intid) 061 static void clk_it(int intid)
060 { 062 {
061 static sos_ui32_t clock_count = 0; 063 static sos_ui32_t clock_count = 0;
062 064
063 display_bits(0, 48, 065 display_bits(0, 48,
064 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 066 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
065 clock_count); 067 clock_count);
066 clock_count++; 068 clock_count++;
067 069
>> 070
>> 071 sos_time_do_tick();
068 } 072 }
069 073
070 !! 074
071 static void pgflt_ex(int exid) !! 075
>> 076
>> 077
>> 078
>> 079
>> 080 static void dump_backtrace(const struct sos_cpu_state *cpu_state,
>> 081 sos_vaddr_t stack_bottom,
>> 082 sos_size_t stack_size,
>> 083 sos_bool_t on_console,
>> 084 sos_bool_t on_bochs)
072 { 085 {
073 sos_bochs_printf("Got page fault\n"); !! 086 static void backtracer(sos_vaddr_t PC,
074 sos_x86_videomem_printf(10, 30, !! 087 sos_vaddr_t params,
075 SOS_X86_VIDEO_FG_LTR !! 088 sos_ui32_t depth,
076 "Got EXPECTED (?) Pa !! 089 void *custom_arg)
077 for (;;) ; !! 090 {
>> 091 sos_ui32_t invalid = 0xffffffff, *arg1, *arg2, *arg3, *arg4;
>> 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_vaddr_t)(v)) \
>> 105 && ((sos_vaddr_t)(v) < (u)) )
>> 106 if (!INTERVAL_OK(stack_bottom, arg1, stack_bottom + stack_size))
>> 107 arg1 = &invalid;
>> 108 if (!INTERVAL_OK(stack_bottom, arg2, stack_bottom + stack_size))
>> 109 arg2 = &invalid;
>> 110 if (!INTERVAL_OK(stack_bottom, arg3, stack_bottom + stack_size))
>> 111 arg3 = &invalid;
>> 112 if (!INTERVAL_OK(stack_bottom, arg4, stack_bottom + stack_size))
>> 113 arg4 = &invalid;
>> 114
>> 115
>> 116 if (on_bochs)
>> 117 sos_bochs_printf("[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x\n",
>> 118 (unsigned)depth, (unsigned)PC,
>> 119 (unsigned)*arg1, (unsigned)*arg2,
>> 120 (unsigned)*arg3);
>> 121
>> 122 if (on_console)
>> 123 sos_x86_videomem_printf(23-depth, 3,
>> 124 SOS_X86_VIDEO_BG_BLUE
>> 125 | SOS_X86_VIDEO_FG_LTGREEN,
>> 126 "[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x arg4=0x%x",
>> 127 (unsigned)depth, PC,
>> 128 (unsigned)*arg1, (unsigned)*arg2,
>> 129 (unsigned)*arg3, (unsigned)*arg4);
>> 130
>> 131 }
>> 132
>> 133 sos_backtrace(cpu_state, 15, stack_bottom, stack_size, backtracer, NULL);
078 } 134 }
079 135
080 static void test_paging(sos_vaddr_t sos_kernel !! 136
>> 137
>> 138 static void pgflt_ex(int intid, const struct sos_cpu_state *ctxt)
081 { 139 {
082 !! 140 static sos_ui32_t demand_paging_count = 0;
083 !! 141 sos_vaddr_t faulting_vaddr = sos_cpu_context_get_EX_faulting_vaddr(ctxt);
084 sos_vaddr_t vpage_code = SOS_PAGE_ALIGN_INF( !! 142 sos_paddr_t ppage_paddr;
085 <<
086 <<
087 sos_paddr_t ppage_new; <<
088 <<
089 <<
090 <<
091 sos_vaddr_t vpage_tmp = sos_kernel_core_top_ <<
092 143
093 unsigned i; !! 144
>> 145 if (! sos_kmem_vmm_is_valid_vaddr(faulting_vaddr))
>> 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 Fault at instruction 0x%x on access to address 0x%x (info=%x)!",
>> 154 sos_cpu_context_get_PC(ctxt),
>> 155 (unsigned)faulting_vaddr,
>> 156 (unsigned)sos_cpu_context_get_EX_info(ctxt));
>> 157 SOS_ASSERT_FATAL(! "Got page fault (note: demand paging is disabled)");
>> 158 }
094 159
095 <<
096 sos_exception_set_routine(SOS_EXCEPT_PAGE_FA <<
097 pgflt_ex); <<
098 160
099 161
100 !! 162
101 <<
102 163
103 sos_x86_videomem_printf(4, 0, !! 164
104 SOS_X86_VIDEO_FG_LTG !! 165
105 "Moving current code !! 166 demand_paging_count ++;
>> 167 display_bits(0, 0,
>> 168 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
>> 169 demand_paging_count);
>> 170
>> 171
>> 172 ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
>> 173 if (! ppage_paddr)
>> 174 SOS_ASSERT_FATAL(! "TODO: implement swap. (Out of mem in demand paging because no swap for kernel yet !)");
>> 175 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(ppage_paddr,
>> 176 SOS_PAGE_ALIGN_INF(faulting_vaddr),
>> 177 FALSE,
>> 178 SOS_VM_MAP_PROT_READ
>> 179 | SOS_VM_MAP_PROT_WRITE
>> 180 | SOS_VM_MAP_ATOMIC));
>> 181 sos_physmem_unref_physpage(ppage_paddr);
>> 182
>> 183
>> 184 }
>> 185
>> 186
>> 187
>> 188
>> 189
>> 190
>> 191
>> 192
>> 193
>> 194 struct thr_arg
>> 195 {
>> 196 char character;
>> 197 int color;
>> 198
>> 199 int col;
>> 200 int row;
>> 201 };
106 202
107 203
108 !! 204 static void demo_thread(void *arg)
109 ppage_new = sos_physmem_ref_physpage_new(FAL !! 205 {
110 if (! ppage_new) !! 206 struct thr_arg *thr_arg = (struct thr_arg*)arg;
>> 207 int progress = 0;
>> 208
>> 209 sos_bochs_printf("start %c", thr_arg->character);
>> 210 while (1)
111 { 211 {
112 !! 212 progress ++;
113 sos_x86_videomem_putstring(20, 0, !! 213 display_bits(thr_arg->row, thr_arg->col+1, thr_arg->color, progress);
114 SOS_X86_VIDEO !! 214
115 | SOS_X86_V !! 215 sos_bochs_putchar(thr_arg->character);
116 "test_paging !! 216
117 return; !! 217
>> 218 if ((random() % 100) == 0)
>> 219 {
>> 220 sos_bochs_printf("[37myield(%c)[m\n", thr_arg->character);
>> 221 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'Y');
>> 222 SOS_ASSERT_FATAL(SOS_OK == sos_thread_yield());
>> 223 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 224 }
>> 225
>> 226
>> 227 else if ((random() % 200) == 0)
>> 228 {
>> 229 struct sos_time t = (struct sos_time){ .sec=0, .nanosec=50000000 };
>> 230 sos_bochs_printf("[37msleep1(%c)[m\n", thr_arg->character);
>> 231 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 's');
>> 232 SOS_ASSERT_FATAL(SOS_OK == sos_thread_sleep(& t));
>> 233 SOS_ASSERT_FATAL(sos_time_is_zero(& t));
>> 234 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 235 }
>> 236
>> 237
>> 238 else if ((random() % 300) == 0)
>> 239 {
>> 240 struct sos_time t = (struct sos_time){ .sec=0, .nanosec=300000000 };
>> 241 sos_bochs_printf("[37msleep2(%c)[m\n", thr_arg->character);
>> 242 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'S');
>> 243 SOS_ASSERT_FATAL(SOS_OK == sos_thread_sleep(& t));
>> 244 SOS_ASSERT_FATAL(sos_time_is_zero(& t));
>> 245 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 246 }
>> 247
>> 248
118 } 249 }
>> 250 }
119 251
120 sos_x86_videomem_printf(5, 0, <<
121 SOS_X86_VIDEO_FG_YEL <<
122 "Hello from the addr <<
123 sos_paging_get_paddr <<
124 <<
125 sos_x86_videomem_printf(6, 0, <<
126 SOS_X86_VIDEO_FG_YEL <<
127 "Transfer vpage 0x%x <<
128 vpage_code, <<
129 sos_paging_get_paddr <<
130 ppage_new, <<
131 (unsigned)vpage_tmp) <<
132 <<
133 <<
134 <<
135 sos_paging_map(ppage_new, vpage_tmp, <<
136 FALSE, <<
137 SOS_VM_MAP_ATOMIC <<
138 | SOS_VM_MAP_PROT_READ <<
139 | SOS_VM_MAP_PROT_WRITE); <<
140 <<
141 <<
142 <<
143 sos_physmem_unref_physpage(ppage_new); <<
144 <<
145 <<
146 <<
147 memcpy((void*)vpage_tmp, <<
148 (void*)vpage_code, <<
149 SOS_PAGE_SIZE); <<
150 <<
151 <<
152 sos_paging_map(ppage_new, vpage_code, <<
153 FALSE, <<
154 SOS_VM_MAP_ATOMIC <<
155 | SOS_VM_MAP_PROT_READ <<
156 | SOS_VM_MAP_PROT_WRITE); <<
157 <<
158 <<
159 <<
160 <<
161 <<
162 <<
163 <<
164 <<
165 sos_paging_unmap(vpage_tmp); <<
166 <<
167 sos_x86_videomem_printf(7, 0, <<
168 SOS_X86_VIDEO_FG_YEL <<
169 "Hello from the addr <<
170 sos_paging_get_paddr <<
171 <<
172 sos_x86_videomem_printf(9, 0, <<
173 SOS_X86_VIDEO_FG_LTG <<
174 "Provoking a page fa <<
175 252
176 !! 253 static void test_thread()
177 !! 254 {
178 !! 255
>> 256
>> 257 static struct thr_arg arg_b, arg_c, arg_d, arg_e, arg_R, arg_S;
>> 258 sos_ui32_t flags;
>> 259
>> 260 sos_disable_IRQs(flags);
>> 261
>> 262 arg_b = (struct thr_arg) { .character='b', .col=0, .row=21, .color=0x14 };
>> 263 sos_create_kernel_thread("YO[b]", demo_thread, (void*)&arg_b);
>> 264
>> 265 arg_c = (struct thr_arg) { .character='c', .col=46, .row=21, .color=0x14 };
>> 266 sos_create_kernel_thread("YO[c]", demo_thread, (void*)&arg_c);
>> 267
>> 268 arg_d = (struct thr_arg) { .character='d', .col=0, .row=20, .color=0x14 };
>> 269 sos_create_kernel_thread("YO[d]", demo_thread, (void*)&arg_d);
>> 270
>> 271 arg_e = (struct thr_arg) { .character='e', .col=0, .row=19, .color=0x14 };
>> 272 sos_create_kernel_thread("YO[e]", demo_thread, (void*)&arg_e);
>> 273
>> 274 arg_R = (struct thr_arg) { .character='R', .col=0, .row=17, .color=0x1c };
>> 275 sos_create_kernel_thread("YO[R]", demo_thread, (void*)&arg_R);
>> 276
>> 277 arg_S = (struct thr_arg) { .character='S', .col=0, .row=16, .color=0x1c };
>> 278 sos_create_kernel_thread("YO[S]", demo_thread, (void*)&arg_S);
179 279
180 !! 280 sos_restore_IRQs(flags);
181 !! 281 }
182 !! 282
183 !! 283
184 for (i = vpage_code ; ; i += SOS_ !! 284
>> 285
>> 286
>> 287
>> 288 static void idle_thread()
>> 289 {
>> 290 sos_ui32_t idle_twiddle = 0;
>> 291
>> 292 while (1)
185 { 293 {
186 unsigned *pint = (unsigned *)SOS_PAGE_AL !! 294
187 sos_bochs_printf("Test vaddr 0x%x : val= !! 295
188 sos_x86_videomem_printf(10, 0, !! 296 asm("hlt\n");
189 SOS_X86_VIDEO_FG !! 297
190 "Test vaddr 0x%x !! 298 idle_twiddle ++;
191 (unsigned)pint); !! 299 display_bits(0, 0, SOS_X86_VIDEO_FG_GREEN | SOS_X86_VIDEO_BG_BLUE,
192 sos_bochs_printf("0x%x\n", *pint); !! 300 idle_twiddle);
193 sos_x86_videomem_printf(10, 30, !! 301
194 SOS_X86_VIDEO_FG !! 302
195 "0x%x " !! 303 sos_thread_yield();
196 } 304 }
197 <<
198 <<
199 sos_x86_videomem_printf(20, 0, <<
200 SOS_X86_VIDEO_FG_LTR <<
201 "We should have had <<
202 vpage_tmp); <<
203 } 305 }
204 306
205 !! 307
>> 308
>> 309
>> 310
206 void sos_main(unsigned long magic, unsigned lo 311 void sos_main(unsigned long magic, unsigned long addr)
207 { 312 {
208 unsigned i; 313 unsigned i;
209 sos_paddr_t sos_kernel_core_base_paddr, sos_ 314 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
>> 315 struct sos_time tick_resolution;
210 316
211 317
212 318
213 319
214 multiboot_info_t *mbi; 320 multiboot_info_t *mbi;
215 mbi = (multiboot_info_t *) addr; 321 mbi = (multiboot_info_t *) addr;
216 322
217 323
218 sos_bochs_setup(); 324 sos_bochs_setup();
219 325
220 sos_x86_videomem_setup(); 326 sos_x86_videomem_setup();
221 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 327 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
222 328
223 329
224 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 330 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
225 331
226 sos_x86_videomem_printf(1, 0, 332 sos_x86_videomem_printf(1, 0,
227 SOS_X86_VIDEO_FG_Y 333 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
228 "Welcome From GRUB 334 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
229 "SOS", ',', !! 335 "SOS article 6.5", ',',
230 (unsigned)(mbi->me 336 (unsigned)(mbi->mem_upper >> 10) + 1,
231 (unsigned)mbi->mem 337 (unsigned)mbi->mem_upper);
232 else 338 else
233 339
234 sos_x86_videomem_printf(1, 0, 340 sos_x86_videomem_printf(1, 0,
235 SOS_X86_VIDEO_FG_Y 341 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
236 "Welcome to SOS"); !! 342 "Welcome to SOS article 6.5");
237 343
238 sos_bochs_putstring("Message in a bochs\n"); !! 344 sos_bochs_putstring("Message in a bochs: This is SOS article 6.5.\n");
239 345
240 346
241 sos_gdt_setup(); !! 347 sos_gdt_subsystem_setup();
242 sos_idt_setup(); !! 348 sos_idt_subsystem_setup();
243 349
244 350
245 sos_exceptions_setup(); !! 351 sos_exception_subsystem_setup();
246 sos_irq_setup(); !! 352 sos_irq_subsystem_setup();
247 353
248 354
249 sos_i8254_set_frequency(100); 355 sos_i8254_set_frequency(100);
250 356
>> 357
>> 358
>> 359 tick_resolution = (struct sos_time) { .sec=0, .nanosec=10000000UL };
>> 360 sos_time_subsysem_setup(& tick_resolution);
251 361
252 362
253 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 363 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
254 { 364 {
255 sos_x86_videomem_putstring(20, 0, 365 sos_x86_videomem_putstring(20, 0,
256 SOS_X86_VIDEO 366 SOS_X86_VIDEO_FG_LTRED
257 | SOS_X86_V 367 | SOS_X86_VIDEO_BG_BLUE
258 | SOS_X86_V 368 | SOS_X86_VIDEO_FG_BLINKING,
259 "I'm not load 369 "I'm not loaded with Grub !");
260 370
261 for (;;) 371 for (;;)
262 continue; 372 continue;
263 } 373 }
264 374
>> 375
>> 376
>> 377
>> 378
265 379
266 sos_irq_set_routine(SOS_IRQ_TIMER, 380 sos_irq_set_routine(SOS_IRQ_TIMER,
267 clk_it); !! 381 clk_it);
268 !! 382
269 !! 383
270 asm volatile ("sti\n"); !! 384
>> 385
>> 386
271 387
272 388
273 389
274 sos_physmem_setup((mbi->mem_upper<<10) + (1< !! 390 sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
275 & sos_kernel_core_base_pad !! 391 & sos_kernel_core_base_paddr,
276 & sos_kernel_core_top_padd !! 392 & sos_kernel_core_top_paddr);
277 393
278 394
279 395
280 396
281 397
282 398
283 399
284 if (sos_paging_setup(sos_kernel_core_base_pa !! 400 SOS_ASSERT_FATAL(SOS_OK ==
285 sos_kernel_core_top_pad !! 401 sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
286 sos_bochs_printf("Could not setup paged me !! 402 sos_kernel_core_top_paddr));
287 sos_x86_videomem_printf(2, 0, !! 403
288 SOS_X86_VIDEO_FG_YEL !! 404
289 "Paged-memory mode i !! 405 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
290 !! 406 pgflt_ex);
291 test_paging(sos_kernel_core_top_paddr); <<
292 <<
293 <<
294 for (;;) <<
295 continue; <<
296 407
297 return; !! 408
>> 409
>> 410
>> 411
>> 412 if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
>> 413 sos_kernel_core_top_paddr,
>> 414 bootstrap_stack_bottom,
>> 415 bootstrap_stack_bottom
>> 416 + bootstrap_stack_size))
>> 417 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
>> 418
>> 419 if (sos_kmalloc_subsystem_setup())
>> 420 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
>> 421
>> 422
>> 423
>> 424
>> 425
>> 426
>> 427 sos_thread_subsystem_setup(bootstrap_stack_bottom,
>> 428 bootstrap_stack_size);
>> 429
>> 430
>> 431 sos_sched_subsystem_setup();
>> 432
>> 433
>> 434 SOS_ASSERT_FATAL(sos_create_kernel_thread("idle", idle_thread, NULL) != NULL);
>> 435
>> 436
>> 437
>> 438 asm volatile ("sti\n");
>> 439
>> 440
>> 441
>> 442 extern void MouseSim();
>> 443 MouseSim();
>> 444 test_thread();
>> 445
>> 446
>> 447
>> 448
>> 449
>> 450
>> 451
>> 452
>> 453
>> 454
>> 455
>> 456
>> 457
>> 458 sos_bochs_printf("Bye from primary thread !\n");
>> 459 sos_thread_exit();
>> 460 SOS_FATAL_ERROR("No trespassing !");
298 } 461 }