Wux Maskot

W OPERATING SYSTEM

Yeni Nesil Monolitik Çekirdek Dağıtım ve Kayıt Portalı

Kuruluş Amblemi

SÜRÜM DETAYI: 0.0.1 Final

Yayın Tarihi: 2026-05-25

Yama Notları:

Güvenlik arttırılmıştır.

ÇEKİRDEK KAYNAK KODU

1 // Copyright (C) 2026 Yusuf Berk Genç (YBG13™)
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12
13 const OS_NAME: ptr<u8> = "W Kernel" as ptr<u8>;
14 const SEC_CORE: ptr<u8> = "Kernel version 0.0.1 final" as ptr<u8>;
15
16 const MB2_MAGIC: u32 = 0xE85250D6;
17 const ARCH_X86_64: u32 = 0;
18 struct MB2Header {
19 magic: u32,
20 arch: u32,
21 length: u32,
22 checksum: u32,
23 }
24 const HEADER: MB2Header = MB2Header {
25 magic: MB2_MAGIC,
26 arch: ARCH_X86_64,
27 length: 16,
28 checksum: -(MB2_MAGIC + ARCH_X86_64 + 16),
29 };
30
31 fn outb(port: u16, data: u8) {
32 asm { "out dx, al" in dx = port; in al = data; }
33 }
34
35 fn outw(port: u16, data: u16) {
36 asm { "out dx, ax" in dx = port; in ax = data; }
37 }
38
39 fn outl(port: u16, data: u32) {
40 asm { "out dx, eax" in dx = port; in eax = data; }
41 }
42
43 fn inb(port: u16) -> u8 {
44 let mut data: u8;
45 asm { "in al, dx" in dx = port; out al = data; }
46 return data;
47 }
48
49 fn inw(port: u16) -> u16 {
50 let mut data: u16;
51 asm { "in ax, dx" in dx = port; out ax = data; }
52 return data;
53 }
54
55 fn inl(port: u16) -> u32 {
56 let mut data: u32;
57 asm { "in eax, dx" in dx = port; out eax = data; }
58 return data;
59 }
60
61 fn cpu_hlt() {
62 asm { "hlt" }
63 }
64
65 fn cpu_cli() {
66 asm { "cli" }
67 }
68
69 fn cpu_sti() {
70 asm { "sti" }
71 }
72
73 fn cpu_pause() {
74 asm { "pause" }
75 }
76
77 fn invlpg(addr: u64) {
78 asm { "invlpg [rax]" in rax = addr; }
79 }
80
81 fn wbinvd() {
82 asm { "wbinvd" }
83 }
84
85 fn cpuid(leaf: u32, subleaf: u32, eax: ptr<u32>, ebx: ptr<u32>, ecx: ptr<u32>, edx: ptr<u32>) {
86 let mut o_eax: u32;
87 let mut o_ebx: u32;
88 let mut o_ecx: u32;
89 let mut o_edx: u32;
90 asm {
91 "cpuid"
92 in eax = leaf;
93 in ecx = subleaf;
94 out eax = o_eax;
95 out ebx = o_ebx;
96 out ecx = o_ecx;
97 out edx = o_edx;
98 }
99 *eax = o_eax;
100 *ebx = o_ebx;
101 *ecx = o_ecx;
102 *edx = o_edx;
103 }
104
105 fn rdmsr(msr: u32) -> u64 {
106 let mut lo: u32;
107 let mut hi: u32;
108 asm {
109 "rdmsr"
110 in ecx = msr;
111 out eax = lo;
112 out edx = hi;
113 }
114 return (hi as u64 << 32) | (lo as u64);
115 }
116
117 fn wrmsr(msr: u32, val: u64) {
118 let lo = (val & 0xFFFFFFFF) as u32;
119 let hi = (val >> 32) as u32;
120 asm {
121 "wrmsr"
122 in ecx = msr;
123 in eax = lo;
124 in edx = hi;
125 }
126 }
127
128 struct Spinlock {
129 locked: u32,
130 }
131
132 fn spin_init(lock: ptr<Spinlock>) {
133 (*lock).locked = 0;
134 }
135
136 fn spin_lock(lock: ptr<Spinlock>) {
137 let mut a = 0;
138 while a == 0 {
139 asm {
140 "lock bts dword [rax], 0\n setnc bl"
141 in rax = lock;
142 out bl = a;
143 }
144 if a == 0 {
145 cpu_pause();
146 }
147 }
148 }
149
150 fn spin_trylock(lock: ptr<Spinlock>) -> u8 {
151 let mut a = 0;
152 asm {
153 "lock bts dword [rax], 0\n setnc bl"
154 in rax = lock;
155 out bl = a;
156 }
157 return a;
158 }
159
160 fn spin_unlock(lock: ptr<Spinlock>) {
161 asm {
162 "lock btr dword [rax], 0"
163 in rax = lock;
164 }
165 }
166
167 struct Mutex {
168 state: u32,
169 owner: u64,
170 }
171
172 fn mutex_init(m: ptr<Mutex>) {
173 (*m).state = 0;
174 (*m).owner = 0;
175 }
176
177 fn memcpy(dest: ptr<u8>, src: ptr<u8>, n: u64) {
178 let mut d = dest as ptr<u64>;
179 let mut s = src as ptr<u64>;
180 let mut len = n / 8;
181 for i in 0..len {
182 *(d + i) = *(s + i);
183 }
184 let mut rem = n % 8;
185 let mut d8 = (dest as u64 + len * 8) as ptr<u8>;
186 let mut s8 = (src as u64 + len * 8) as ptr<u8>;
187 for i in 0..rem {
188 *(d8 + i) = *(s8 + i);
189 }
190 }
191
192 fn memset(dest: ptr<u8>, val: u8, n: u64) {
193 let v64: u64 = (val as u64) | ((val as u64) << 8) | ((val as u64) << 16) | ((val as u64) << 24) | ((val as u64) << 32) | ((val as u64) << 40) | ((val as u64) << 48) | ((val as u64) << 56);
194 let mut d = dest as ptr<u64>;
195 let mut len = n / 8;
196 for i in 0..len {
197 *(d + i) = v64;
198 }
199 let mut rem = n % 8;
200 let mut d8 = (dest as u64 + len * 8) as ptr<u8>;
201 for i in 0..rem {
202 *(d8 + i) = val;
203 }
204 }
205
206 fn memcmp(p1: ptr<u8>, p2: ptr<u8>, n: u64) -> i32 {
207 for i in 0..n {
208 if *(p1 + i) != *(p2 + i) {
209 return (*(p1 + i) - *(p2 + i)) as i32;
210 }
211 }
212 return 0;
213 }
214
215 fn memmove(dest: ptr<u8>, src: ptr<u8>, n: u64) {
216 if dest < src {
217 memcpy(dest, src, n);
218 } else {
219 for i in (0..n).rev() {
220 *(dest + i) = *(src + i);
221 }
222 }
223 }
224
225 fn strlen(s: ptr<u8>) -> u64 {
226 let mut l: u64 = 0;
227 while *(s + l) != 0 {
228 l = l + 1;
229 }
230 return l;
231 }
232
233 fn strcpy(dest: ptr<u8>, src: ptr<u8>) {
234 let mut i: u64 = 0;
235 while *(src + i) != 0 {
236 *(dest + i) = *(src + i);
237 i = i + 1;
238 }
239 *(dest + i) = 0;
240 }
241
242 fn strcmp(s1: ptr<u8>, s2: ptr<u8>) -> i32 {
243 let mut i: u64 = 0;
244 while *(s1 + i) != 0 && *(s2 + i) != 0 {
245 if *(s1 + i) != *(s2 + i) {
246 return (*(s1 + i) - *(s2 + i)) as i32;
247 }
248 i = i + 1;
249 }
250 return (*(s1 + i) - *(s2 + i)) as i32;
251 }
252
253 struct GDTEntry {
254 limit_low: u16,
255 base_low: u16,
256 base_mid: u8,
257 access: u8,
258 flags_limit: u8,
259 base_hi: u8,
260 }
261
262 struct TSSEntry {
263 rsv0: u32,
264 rsp0: u64,
265 rsp1: u64,
266 rsp2: u64,
267 rsv1: u64,
268 ist1: u64,
269 ist2: u64,
270 ist3: u64,
271 ist4: u64,
272 ist5: u64,
273 ist6: u64,
274 ist7: u64,
275 rsv2: u64,
276 rsv3: u16,
277 iomap_base: u16,
278 }
279
280 struct GDTDesc {
281 limit: u16,
282 base: u64,
283 }
284
285 let mut gdt: [GDTEntry; 11];
286 let mut tss: [TSSEntry; 4];
287 let mut gdt_d: GDTDesc;
288
289 fn set_gdt_entry(n: u64, base: u64, limit: u32, access: u8, flags: u8) {
290 gdt[n].base_low = (base & 0xFFFF) as u16;
291 gdt[n].base_mid = ((base >> 16) & 0xFF) as u8;
292 gdt[n].base_hi = ((base >> 24) & 0xFF) as u8;
293 gdt[n].limit_low = (limit & 0xFFFF) as u16;
294 gdt[n].flags_limit = (((limit >> 16) & 0x0F) as u8) | (flags & 0xF0);
295 gdt[n].access = access;
296 }
297
298 fn init_gdt_64() {
299 gdt_d.limit = (sizeof(GDTEntry) * 11) - 1;
300 gdt_d.base = gdt as u64;
301
302 set_gdt_entry(0, 0, 0, 0, 0);
303 set_gdt_entry(1, 0, 0xFFFFF, 0x9A, 0xA0);
304 set_gdt_entry(2, 0, 0xFFFFF, 0x92, 0xA0);
305 set_gdt_entry(3, 0, 0xFFFFF, 0xFA, 0xA0);
306 set_gdt_entry(4, 0, 0xFFFFF, 0xF2, 0xA0);
307
308 let tss_b0 = &tss[0] as u64;
309 set_gdt_entry(5, tss_b0, sizeof(TSSEntry) as u32, 0x89, 0x40);
310 set_gdt_entry(6, tss_b0 >> 32, 0, 0, 0);
311
312 asm {
313 "lgdt [rax]\n"
314 "push 0x08\n"
315 "lea rax, [rip + .next]\n"
316 "push rax\n"
317 "retfq\n"
318 ".next:\n"
319 "mov ax, 0x10\n"
320 "mov ds, ax\n"
321 "mov es, ax\n"
322 "mov fs, ax\n"
323 "mov gs, ax\n"
324 "mov ss, ax\n"
325 "mov ax, 0x28\n"
326 "ltr ax"
327 in rax = &gdt_d;
328 }
329 }
330
331 struct IDTEntry {
332 offset_low: u16,
333 selector: u16,
334 ist: u8,
335 flags: u8,
336 offset_mid: u16,
337 offset_high: u32,
338 reserved: u32,
339 }
340
341 struct IDTDesc {
342 limit: u16,
343 base: u64,
344 }
345
346 let mut idt: [IDTEntry; 256];
347 let mut idt_d: IDTDesc;
348
349 fn set_idt_entry(n: u8, base: u64, selector: u16, flags: u8, ist: u8) {
350 idt[n].offset_low = (base & 0xFFFF) as u16;
351 idt[n].offset_mid = ((base >> 16) & 0xFFFF) as u16;
352 idt[n].offset_high = (base >> 32) as u32;
353 idt[n].selector = selector;
354 idt[n].ist = ist;
355 idt[n].flags = flags;
356 idt[n].reserved = 0;
357 }
358
359 fn isr_stub_common() {
360 asm {
361 "push rax\n push rcx\n push rdx\n push r8\n push r9\n push r10\n push r11\n"
362 "mov al, 0x20\n out 0x20, al\n"
363 "pop r11\n pop r10\n pop r9\n pop r8\n pop rdx\n pop rcx\n pop rax\n"
364 "iretq"
365 }
366 }
367
368 fn exc_div_zero() { asm { "cli\n hlt" } }
369 fn exc_debug() { asm { "cli\n hlt" } }
370 fn exc_nmi() { asm { "cli\n hlt" } }
371 fn exc_breakpoint() { asm { "cli\n hlt" } }
372 fn exc_overflow() { asm { "cli\n hlt" } }
373 fn exc_bound() { asm { "cli\n hlt" } }
374 fn exc_invalid_op() { asm { "cli\n hlt" } }
375 fn exc_device_not_avail() { asm { "cli\n hlt" } }
376 fn exc_double_fault() { asm { "cli\n hlt" } }
377 fn exc_coproc_seg() { asm { "cli\n hlt" } }
378 fn exc_invalid_tss() { asm { "cli\n hlt" } }
379 fn exc_segment_not_present() { asm { "cli\n hlt" } }
380 fn exc_stack_fault() { asm { "cli\n hlt" } }
381 fn exc_general_protect() { asm { "cli\n hlt" } }
382 fn exc_page_fault() { asm { "cli\n hlt" } }
383 fn exc_fpu_error() { asm { "cli\n hlt" } }
384 fn exc_alignment_check() { asm { "cli\n hlt" } }
385 fn exc_machine_check() { asm { "cli\n hlt" } }
386 fn exc_simd_fault() { asm { "cli\n hlt" } }
387
388 fn init_idt_64() {
389 idt_d.limit = (sizeof(IDTEntry) * 256) - 1;
390 idt_d.base = idt as u64;
391
392 set_idt_entry(0, exc_div_zero as u64, 0x08, 0x8E, 0);
393 set_idt_entry(1, exc_debug as u64, 0x08, 0x8E, 0);
394 set_idt_entry(2, exc_nmi as u64, 0x08, 0x8E, 1);
395 set_idt_entry(3, exc_breakpoint as u64, 0x08, 0x8E, 0);
396 set_idt_entry(4, exc_overflow as u64, 0x08, 0x8E, 0);
397 set_idt_entry(5, exc_bound as u64, 0x08, 0x8E, 0);
398 set_idt_entry(6, exc_invalid_op as u64, 0x08, 0x8E, 0);
399 set_idt_entry(7, exc_device_not_avail as u64, 0x08, 0x8E, 0);
400 set_idt_entry(8, exc_double_fault as u64, 0x08, 0x8E, 2);
401 set_idt_entry(9, exc_coproc_seg as u64, 0x08, 0x8E, 0);
402 set_idt_entry(10, exc_invalid_tss as u64, 0x08, 0x8E, 0);
403 set_idt_entry(11, exc_segment_not_present as u64, 0x08, 0x8E, 0);
404 set_idt_entry(12, exc_stack_fault as u64, 0x08, 0x8E, 0);
405 set_idt_entry(13, exc_general_protect as u64, 0x08, 0x8E, 0);
406 set_idt_entry(14, exc_page_fault as u64, 0x08, 0x8E, 0);
407 set_idt_entry(16, exc_fpu_error as u64, 0x08, 0x8E, 0);
408 set_idt_entry(17, exc_alignment_check as u64, 0x08, 0x8E, 0);
409 set_idt_entry(18, exc_machine_check as u64, 0x08, 0x8E, 0);
410 set_idt_entry(19, exc_simd_fault as u64, 0x08, 0x8E, 0);
411
412 for i in 32..256 {
413 set_idt_entry(i as u8, isr_stub_common as u64, 0x08, 0x8E, 0);
414 }
415
416 asm { "lidt [rax]\n sti" in rax = &idt_d; }
417 }
418 const PAGE_SIZE: u64 = 4096;
419 const MAX_MEM_MB: u64 = 32768;
420 const PMM_BITMAP_SIZE: u64 = (MAX_MEM_MB * 1024 * 1024) / (PAGE_SIZE * 64);
421
422 let mut pmm_bitmap: [u64; PMM_BITMAP_SIZE as usize];
423 let mut pmm_lock: Spinlock;
424 let mut pmm_used_blocks: u64 = 0;
425 let mut pmm_max_blocks: u64 = 0;
426
427 fn pmm_bitmap_set(bit: u64) {
428 pmm_bitmap[(bit / 64) as usize] |= 1 << (bit % 64);
429 }
430
431 fn pmm_bitmap_unset(bit: u64) {
432 pmm_bitmap[(bit / 64) as usize] &= !(1 << (bit % 64));
433 }
434
435 fn pmm_bitmap_test(bit: u64) -> bool {
436 return (pmm_bitmap[(bit / 64) as usize] & (1 << (bit % 64))) != 0;
437 }
438
439 fn pmm_init(mem_size_kb: u64) {
440 spin_init(&pmm_lock);
441 pmm_max_blocks = (mem_size_kb * 1024) / PAGE_SIZE;
442 pmm_used_blocks = pmm_max_blocks;
443 memset(pmm_bitmap as ptr<u8>, 0xFF, (PMM_BITMAP_SIZE * 8) as u64);
444 }
445
446 fn pmm_init_region(base: u64, size: u64) {
447 spin_lock(&pmm_lock);
448 let align_base = base / PAGE_SIZE;
449 let blocks = size / PAGE_SIZE;
450 for i in 0..blocks {
451 pmm_bitmap_unset(align_base + i);
452 pmm_used_blocks = pmm_used_blocks - 1;
453 }
454 spin_unlock(&pmm_lock);
455 pmm_bitmap_set(0);
456 }
457
458 fn pmm_deinit_region(base: u64, size: u64) {
459 spin_lock(&pmm_lock);
460 let align_base = base / PAGE_SIZE;
461 let blocks = size / PAGE_SIZE;
462 for i in 0..blocks {
463 pmm_bitmap_set(align_base + i);
464 pmm_used_blocks = pmm_used_blocks + 1;
465 }
466 spin_unlock(&pmm_lock);
467 }
468
469 fn pmm_alloc_block() -> u64 {
470 spin_lock(&pmm_lock);
471 if pmm_used_blocks == pmm_max_blocks {
472 spin_unlock(&pmm_lock);
473 return 0;
474 }
475 for i in 0..(PMM_BITMAP_SIZE as u64) {
476 if pmm_bitmap[i as usize] != 0xFFFFFFFFFFFFFFFF {
477 for j in 0..64 {
478 let bit = i * 64 + j;
479 if !pmm_bitmap_test(bit) {
480 pmm_bitmap_set(bit);
481 pmm_used_blocks = pmm_used_blocks + 1;
482 spin_unlock(&pmm_lock);
483 return bit * PAGE_SIZE;
484 }
485 }
486 }
487 }
488 spin_unlock(&pmm_lock);
489 return 0;
490 }
491
492 fn pmm_free_block(addr: u64) {
493 spin_lock(&pmm_lock);
494 let bit = addr / PAGE_SIZE;
495 if pmm_bitmap_test(bit) {
496 pmm_bitmap_unset(bit);
497 pmm_used_blocks = pmm_used_blocks - 1;
498 }
499 spin_unlock(&pmm_lock);
500 }
501
502 fn pmm_alloc_blocks(count: u64) -> u64 {
503 spin_lock(&pmm_lock);
504 if pmm_used_blocks + count > pmm_max_blocks {
505 spin_unlock(&pmm_lock);
506 return 0;
507 }
508 let mut free_count: u64 = 0;
509 let mut start_bit: u64 = 0;
510 for i in 0..(pmm_max_blocks) {
511 if !pmm_bitmap_test(i) {
512 if free_count == 0 {
513 start_bit = i;
514 }
515 free_count = free_count + 1;
516 if free_count == count {
517 for j in 0..count {
518 pmm_bitmap_set(start_bit + j);
519 }
520 pmm_used_blocks = pmm_used_blocks + count;
521 spin_unlock(&pmm_lock);
522 return start_bit * PAGE_SIZE;
523 }
524 } else {
525 free_count = 0;
526 }
527 }
528 spin_unlock(&pmm_lock);
529 return 0;
530 }
531
532 fn pmm_free_blocks(addr: u64, count: u64) {
533 spin_lock(&pmm_lock);
534 let start_bit = addr / PAGE_SIZE;
535 for i in 0..count {
536 if pmm_bitmap_test(start_bit + i) {
537 pmm_bitmap_unset(start_bit + i);
538 pmm_used_blocks = pmm_used_blocks - 1;
539 }
540 }
541 spin_unlock(&pmm_lock);
542 }
543
544 struct PageTableEntry {
545 entry: u64,
546 }
547
548 fn pte_set_flag(pte: ptr<PageTableEntry>, flag: u64) {
549 (*pte).entry |= flag;
550 }
551
552 fn pte_clear_flag(pte: ptr<PageTableEntry>, flag: u64) {
553 (*pte).entry &= !flag;
554 }
555
556 fn pte_set_frame(pte: ptr<PageTableEntry>, frame: u64) {
557 (*pte).entry = ((*pte).entry & 0xFFF) | (frame & 0xFFFFFFFFFFFFF000);
558 }
559
560 fn pte_is_present(pte: ptr<PageTableEntry>) -> bool {
561 return ((*pte).entry & 1) != 0;
562 }
563
564 fn pte_get_frame(pte: ptr<PageTableEntry>) -> u64 {
565 return (*pte).entry & 0x000FFFFFFFFFF000;
566 }
567
568 struct PageTable {
569 entries: [PageTableEntry; 512],
570 }
571
572 let mut vmm_pml4: ptr<PageTable>;
573 let mut vmm_lock: Spinlock;
574
575 fn vmm_init() {
576 spin_init(&vmm_lock);
577 let pml4_phys = pmm_alloc_block();
578 vmm_pml4 = pml4_phys as ptr<PageTable>;
579 memset(vmm_pml4 as ptr<u8>, 0, PAGE_SIZE);
580
581 let mut phys: u64 = 0;
582 while phys < 0x200000000 {
583 vmm_map_page(phys, phys, 3);
584 phys = phys + PAGE_SIZE;
585 }
586 asm { "mov cr3, rax" in rax = pml4_phys; }
587 }
588
589 fn vmm_get_pt_index(virt: u64) -> (u64, u64, u64, u64) {
590 let pml4_idx = (virt >> 39) & 0x1FF;
591 let pdpt_idx = (virt >> 30) & 0x1FF;
592 let pd_idx = (virt >> 21) & 0x1FF;
593 let pt_idx = (virt >> 12) & 0x1FF;
594 return (pml4_idx, pdpt_idx, pd_idx, pt_idx);
595 }
596
597 fn vmm_map_page(phys: u64, virt: u64, flags: u64) {
598 spin_lock(&vmm_lock);
599 let (pml4_i, pdpt_i, pd_i, pt_i) = vmm_get_pt_index(virt);
600
601 let mut pml4e = &((*vmm_pml4).entries[pml4_i as usize]) as ptr<PageTableEntry>;
602 if !pte_is_present(pml4e) {
603 let new_pdpt = pmm_alloc_block();
604 memset(new_pdpt as ptr<u8>, 0, PAGE_SIZE);
605 pte_set_frame(pml4e, new_pdpt);
606 pte_set_flag(pml4e, 3);
607 }
608
609 let pdpt = pte_get_frame(pml4e) as ptr<PageTable>;
610 let mut pdpte = &((*pdpt).entries[pdpt_i as usize]) as ptr<PageTableEntry>;
611 if !pte_is_present(pdpte) {
612 let new_pd = pmm_alloc_block();
613 memset(new_pd as ptr<u8>, 0, PAGE_SIZE);
614 pte_set_frame(pdpte, new_pd);
615 pte_set_flag(pdpte, 3);
616 }
617
618 let pd = pte_get_frame(pdpte) as ptr<PageTable>;
619 let mut pde = &((*pd).entries[pd_i as usize]) as ptr<PageTableEntry>;
620 if !pte_is_present(pde) {
621 let new_pt = pmm_alloc_block();
622 memset(new_pt as ptr<u8>, 0, PAGE_SIZE);
623 pte_set_frame(pde, new_pt);
624 pte_set_flag(pde, 3);
625 }
626
627 let pt = pte_get_frame(pde) as ptr<PageTable>;
628 let mut pte = &((*pt).entries[pt_i as usize]) as ptr<PageTableEntry>;
629 pte_set_frame(pte, phys);
630 pte_set_flag(pte, flags | 1);
631
632 invlpg(virt);
633 spin_unlock(&vmm_lock);
634 }
635
636 fn vmm_unmap_page(virt: u64) {
637 spin_lock(&vmm_lock);
638 let (pml4_i, pdpt_i, pd_i, pt_i) = vmm_get_pt_index(virt);
639
640 let pml4e = &((*vmm_pml4).entries[pml4_i as usize]) as ptr<PageTableEntry>;
641 if !pte_is_present(pml4e) { spin_unlock(&vmm_lock); return; }
642
643 let pdpt = pte_get_frame(pml4e) as ptr<PageTable>;
644 let pdpte = &((*pdpt).entries[pdpt_i as usize]) as ptr<PageTableEntry>;
645 if !pte_is_present(pdpte) { spin_unlock(&vmm_lock); return; }
646
647 let pd = pte_get_frame(pdpte) as ptr<PageTable>;
648 let pde = &((*pd).entries[pd_i as usize]) as ptr<PageTableEntry>;
649 if !pte_is_present(pde) { spin_unlock(&vmm_lock); return; }
650
651 let pt = pte_get_frame(pde) as ptr<PageTable>;
652 let pte = &((*pt).entries[pt_i as usize]) as ptr<PageTableEntry>;
653
654 pte_clear_flag(pte, 1);
655 (*pte).entry = 0;
656
657 invlpg(virt);
658 spin_unlock(&vmm_lock);
659 }
660
661 fn vmm_get_phys(virt: u64) -> u64 {
662 let (pml4_i, pdpt_i, pd_i, pt_i) = vmm_get_pt_index(virt);
663
664 let pml4e = &((*vmm_pml4).entries[pml4_i as usize]) as ptr<PageTableEntry>;
665 if !pte_is_present(pml4e) { return 0; }
666
667 let pdpt = pte_get_frame(pml4e) as ptr<PageTable>;
668 let pdpte = &((*pdpt).entries[pdpt_i as usize]) as ptr<PageTableEntry>;
669 if !pte_is_present(pdpte) { return 0; }
670
671 let pd = pte_get_frame(pdpte) as ptr<PageTable>;
672 let pde = &((*pd).entries[pd_i as usize]) as ptr<PageTableEntry>;
673 if !pte_is_present(pde) { return 0; }
674
675 let pt = pte_get_frame(pde) as ptr<PageTable>;
676 let pte = &((*pt).entries[pt_i as usize]) as ptr<PageTableEntry>;
677 if !pte_is_present(pte) { return 0; }
678
679 return pte_get_frame(pte) | (virt & 0xFFF);
680 }
681
682 struct RSDPDescriptor {
683 signature: [u8; 8],
684 checksum: u8,
685 oem_id: [u8; 6],
686 revision: u8,
687 rsdt_address: u32,
688 }
689
690 struct RSDPDescriptor20 {
691 first_part: RSDPDescriptor,
692 length: u32,
693 xsdt_address: u64,
694 extended_checksum: u8,
695 reserved: [u8; 3],
696 }
697
698 struct ACPISDTHeader {
699 signature: [u8; 4],
700 length: u32,
701 revision: u8,
702 checksum: u8,
703 oem_id: [u8; 6],
704 oem_table_id: [u8; 8],
705 oem_revision: u32,
706 creator_id: u32,
707 creator_revision: u32,
708 }
709
710 struct MADTHeader {
711 header: ACPISDTHeader,
712 local_apic_addr: u32,
713 flags: u32,
714 }
715
716 struct MCFGHeader {
717 header: ACPISDTHeader,
718 reserved: u64,
719 }
720
721 struct FADTHeader {
722 header: ACPISDTHeader,
723 firmware_ctrl: u32,
724 dsdt: u32,
725 reserved: u8,
726 preferred_pm_profile: u8,
727 sci_interrupt: u16,
728 smi_cmd_port: u32,
729 acpi_enable: u8,
730 acpi_disable: u8,
731 s4bios_req: u8,
732 pstate_cnt: u8,
733 pm1a_event_block: u32,
734 pm1b_event_block: u32,
735 pm1a_control_block: u32,
736 pm1b_control_block: u32,
737 pm2_control_block: u32,
738 pm_timer_block: u32,
739 gpe0_block: u32,
740 gpe1_block: u32,
741 }
742
743 let mut acpi_rsdp: ptr<RSDPDescriptor20>;
744 let mut acpi_madt: ptr<MADTHeader>;
745 let mut acpi_mcfg: ptr<MCFGHeader>;
746 let mut acpi_fadt: ptr<FADTHeader>;
747 let mut global_lapic_base: u64 = 0xFEE00000;
748 let mut global_ioapic_base: u64 = 0xFEC00000;
749
750 fn acpi_checksum(ptr: ptr<u8>, length: u32) -> bool {
751 let mut sum: u8 = 0;
752 for i in 0..length {
753 sum = sum + *(ptr + i as u64);
754 }
755 return sum == 0;
756 }
757
758 fn acpi_find_rsdp() -> ptr<RSDPDescriptor20> {
759 let mut current: u64 = 0x000E0000;
760 while current < 0x000FFFFF {
761 if memcmp(current as ptr<u8>, "RSD PTR " as ptr<u8>, 8) == 0 {
762 if acpi_checksum(current as ptr<u8>, 20) {
763 return current as ptr<RSDPDescriptor20>;
764 }
765 }
766 current = current + 16;
767 }
768 return 0 as ptr<RSDPDescriptor20>;
769 }
770
771 fn acpi_parse_madt(madt: ptr<MADTHeader>) {
772 global_lapic_base = (*madt).local_apic_addr as u64;
773 let mut current_ptr = (madt as u64 + sizeof(MADTHeader) as u64) as ptr<u8>;
774 let end_ptr = (madt as u64 + (*madt).header.length as u64) as ptr<u8>;
775
776 while current_ptr < end_ptr {
777 let rec_type = *current_ptr;
778 let rec_len = *(current_ptr + 1);
779 if rec_type == 0 {
780 } else if rec_type == 1 {
781 let ioapic_addr = *((current_ptr + 4) as ptr<u32>);
782 global_ioapic_base = ioapic_addr as u64;
783 } else if rec_type == 2 {
784 }
785 current_ptr = current_ptr + rec_len as u64;
786 }
787 }
788
789 fn acpi_init() {
790 acpi_rsdp = acpi_find_rsdp();
791 if acpi_rsdp == 0 as ptr<RSDPDescriptor20> { return; }
792
793 let xsdt = (*acpi_rsdp).xsdt_address as ptr<ACPISDTHeader>;
794 if xsdt as u64 != 0 && acpi_checksum(xsdt as ptr<u8>, (*xsdt).length) {
795 let entries = ((*xsdt).length - sizeof(ACPISDTHeader) as u32) / 8;
796 let table_ptrs = (xsdt as u64 + sizeof(ACPISDTHeader) as u64) as ptr<u64>;
797
798 for i in 0..entries {
799 let header = *(table_ptrs + i as u64) as ptr<ACPISDTHeader>;
800 if memcmp((*header).signature as ptr<u8>, "APIC" as ptr<u8>, 4) == 0 {
801 acpi_madt = header as ptr<MADTHeader>;
802 acpi_parse_madt(acpi_madt);
803 } else if memcmp((*header).signature as ptr<u8>, "MCFG" as ptr<u8>, 4) == 0 {
804 acpi_mcfg = header as ptr<MCFGHeader>;
805 } else if memcmp((*header).signature as ptr<u8>, "FACP" as ptr<u8>, 4) == 0 {
806 acpi_fadt = header as ptr<FADTHeader>;
807 }
808 }
809 }
810 }
811
812 const LAPIC_ID: u32 = 0x0020;
813 const LAPIC_VER: u32 = 0x0030;
814 const LAPIC_TPR: u32 = 0x0080;
815 const LAPIC_APR: u32 = 0x0090;
816 const LAPIC_PPR: u32 = 0x00A0;
817 const LAPIC_EOI: u32 = 0x00B0;
818 const LAPIC_RRD: u32 = 0x00C0;
819 const LAPIC_LDR: u32 = 0x00D0;
820 const LAPIC_DFR: u32 = 0x00E0;
821 const LAPIC_SVR: u32 = 0x00F0;
822 const LAPIC_ISR: u32 = 0x0100;
823 const LAPIC_TMR: u32 = 0x0180;
824 const LAPIC_IRR: u32 = 0x0200;
825 const LAPIC_ESR: u32 = 0x0280;
826 const LAPIC_ICRLO: u32 = 0x0300;
827 const LAPIC_ICRHI: u32 = 0x0310;
828 const LAPIC_TIMER: u32 = 0x0320;
829 const LAPIC_THERMAL: u32 = 0x0330;
830 const LAPIC_PERF: u32 = 0x0340;
831 const LAPIC_LINT0: u32 = 0x0350;
832 const LAPIC_LINT1: u32 = 0x0360;
833 const LAPIC_ERROR: u32 = 0x0370;
834 const LAPIC_TICR: u32 = 0x0380;
835 const LAPIC_TCCR: u32 = 0x0390;
836 const LAPIC_TDCR: u32 = 0x03E0;
837
838 fn lapic_write(reg: u32, val: u32) {
839 let ptr = (global_lapic_base + reg as u64) as ptr<u32>;
840 *ptr = val;
841 }
842
843 fn lapic_read(reg: u32) -> u32 {
844 let ptr = (global_lapic_base + reg as u64) as ptr<u32>;
845 return *ptr;
846 }
847
848 fn lapic_eoi() {
849 lapic_write(LAPIC_EOI, 0);
850 }
851
852 fn lapic_init_cpu() {
853 lapic_write(LAPIC_DFR, 0xFFFFFFFF);
854 lapic_write(LAPIC_LDR, (lapic_read(LAPIC_LDR) & 0x00FFFFFF) | 1);
855 lapic_write(LAPIC_LINT0, 0x10000);
856 lapic_write(LAPIC_LINT1, 0x10000);
857 lapic_write(LAPIC_TPR, 0);
858 lapic_write(LAPIC_SVR, 0x1FF);
859 }
860
861 fn ioapic_write(reg: u8, val: u32) {
862 let sel = global_ioapic_base as ptr<u32>;
863 let win = (global_ioapic_base + 0x10) as ptr<u32>;
864 *sel = reg as u32;
865 *win = val;
866 }
867
868 fn ioapic_read(reg: u8) -> u32 {
869 let sel = global_ioapic_base as ptr<u32>;
870 let win = (global_ioapic_base + 0x10) as ptr<u32>;
871 *sel = reg as u32;
872 return *win;
873 }
874
875 fn ioapic_set_entry(irq: u8, vector: u8, apic_id: u8) {
876 let low_idx = 0x10 + irq * 2;
877 let high_idx = 0x10 + irq * 2 + 1;
878 let low_val = vector as u32;
879 let high_val = (apic_id as u32) << 24;
880 ioapic_write(low_idx, low_val);
881 ioapic_write(high_idx, high_val);
882 }
883
884 struct MCFGAllocation {
885 base_address: u64,
886 pci_segment_group: u16,
887 start_bus_number: u8,
888 end_bus_number: u8,
889 reserved: u32,
890 }
891
892 struct PCIDeviceExt {
893 base: u64,
894 seg: u16,
895 bus: u8,
896 dev: u8,
897 func: u8,
898 vendor_id: u16,
899 device_id: u16,
900 class_code: u8,
901 subclass: u8,
902 prog_if: u8,
903 bar0: u64,
904 bar1: u64,
905 bar2: u64,
906 bar3: u64,
907 bar4: u64,
908 bar5: u64,
909 irq: u8,
910 }
911
912 let mut pcie_devices: [PCIDeviceExt; 2048];
913 let mut pcie_device_count: u64 = 0;
914
915 fn pcie_read_16(base: u64, bus: u8, dev: u8, func: u8, offset: u16) -> u16 {
916 let addr = base | ((bus as u64) << 20) | ((dev as u64) << 15) | ((func as u64) << 12) | (offset as u64);
917 return *(addr as ptr<u16>);
918 }
919
920 fn pcie_read_32(base: u64, bus: u8, dev: u8, func: u8, offset: u16) -> u32 {
921 let addr = base | ((bus as u64) << 20) | ((dev as u64) << 15) | ((func as u64) << 12) | (offset as u64);
922 return *(addr as ptr<u32>);
923 }
924
925 fn pcie_write_32(base: u64, bus: u8, dev: u8, func: u8, offset: u16, val: u32) {
926 let addr = base | ((bus as u64) << 20) | ((dev as u64) << 15) | ((func as u64) << 12) | (offset as u64);
927 *(addr as ptr<u32>) = val;
928 }
929
930 fn pcie_scan_bus(base: u64, seg: u16, bus: u8) {
931 for dev in 0..32 {
932 let vendor = pcie_read_16(base, bus, dev as u8, 0, 0x00);
933 if vendor != 0xFFFF {
934 pcie_scan_func(base, seg, bus, dev as u8, 0);
935 let header_type = (pcie_read_32(base, bus, dev as u8, 0, 0x0C) >> 16) & 0xFF;
936 if (header_type & 0x80) != 0 {
937 for func in 1..8 {
938 if pcie_read_16(base, bus, dev as u8, func as u8, 0x00) != 0xFFFF {
939 pcie_scan_func(base, seg, bus, dev as u8, func as u8);
940 }
941 }
942 }
943 }
944 }
945 }
946
947 fn pcie_scan_func(base: u64, seg: u16, bus: u8, dev: u8, func: u8) {
948 let vendor = pcie_read_16(base, bus, dev, func, 0x00);
949 let device = pcie_read_16(base, bus, dev, func, 0x02);
950 let class_info = pcie_read_32(base, bus, dev, func, 0x08);
951 let irq_info = pcie_read_32(base, bus, dev, func, 0x3C);
952
953 let mut ext: PCIDeviceExt;
954 ext.base = base;
955 ext.seg = seg;
956 ext.bus = bus;
957 ext.dev = dev;
958 ext.func = func;
959 ext.vendor_id = vendor;
960 ext.device_id = device;
961 ext.class_code = (class_info >> 24) as u8;
962 ext.subclass = (class_info >> 16) as u8;
963 ext.prog_if = (class_info >> 8) as u8;
964 ext.irq = (irq_info & 0xFF) as u8;
965
966 let b0 = pcie_read_32(base, bus, dev, func, 0x10);
967 if (b0 & 4) != 0 {
968 ext.bar0 = (b0 & 0xFFFFFFF0) as u64 | ((pcie_read_32(base, bus, dev, func, 0x14) as u64) << 32);
969 } else {
970 ext.bar0 = (b0 & 0xFFFFFFF0) as u64;
971 }
972
973 let b5 = pcie_read_32(base, bus, dev, func, 0x24);
974 if (b5 & 4) != 0 {
975 ext.bar5 = (b5 & 0xFFFFFFF0) as u64 | ((pcie_read_32(base, bus, dev, func, 0x28) as u64) << 32);
976 } else {
977 ext.bar5 = (b5 & 0xFFFFFFF0) as u64;
978 }
979
980 pcie_devices[pcie_device_count as usize] = ext;
981 pcie_device_count = pcie_device_count + 1;
982 }
983
984 fn pcie_init() {
985 if acpi_mcfg == 0 as ptr<MCFGHeader> { return; }
986 let entries = ((*acpi_mcfg).header.length - sizeof(MCFGHeader) as u32) / sizeof(MCFGAllocation) as u32;
987 let allocs = (acpi_mcfg as u64 + sizeof(MCFGHeader) as u64) as ptr<MCFGAllocation>;
988
989 for i in 0..entries {
990 let alloc = &(*allocs.offset(i as isize));
991 for bus in (*alloc).start_bus_number..=(*alloc).end_bus_number {
992 pcie_scan_bus((*alloc).base_address, (*alloc).pci_segment_group, bus);
993 }
994 }
995 }
996
997 struct AHCIPortRegs {
998 clb: u64,
999 fb: u64,
1000 is: u32,
1001 ie: u32,
1002 cmd: u32,
1003 rsv0: u32,
1004 tfd: u32,
1005 sig: u32,
1006 ssts: u32,
1007 sctl: u32,
1008 serr: u32,
1009 sact: u32,
1010 ci: u32,
1011 sntf: u32,
1012 fbs: u32,
1013 devslp: u32,
1014 rsv1: [u32; 10],
1015 vendor: [u32; 4],
1016 }
1017
1018 struct AHCIHBARegs {
1019 cap: u32,
1020 ghc: u32,
1021 is: u32,
1022 pi: u32,
1023 vs: u32,
1024 ccc_ctl: u32,
1025 ccc_pts: u32,
1026 em_loc: u32,
1027 em_ctl: u32,
1028 cap2: u32,
1029 bohc: u32,
1030 rsv: [u8; 116],
1031 ports: [AHCIPortRegs; 32],
1032 }
1033
1034 struct AHCICmdHeader {
1035 cfl_p_r_c: u16,
1036 prdtl: u16,
1037 prdbc: u32,
1038 ctba: u64,
1039 rsv1: [u32; 4],
1040 }
1041
1042 struct AHCIPRDTEntry {
1043 dba: u64,
1044 rsv0: u32,
1045 dbc_i: u32,
1046 }
1047
1048 struct AHCICmdTable {
1049 cfis: [u8; 64],
1050 acmd: [u8; 16],
1051 rsv: [u8; 48],
1052 prdt_entry: [AHCIPRDTEntry; 65536 / 8],
1053 }
1054
1055 let mut global_ahci_hba: ptr<AHCIHBARegs>;
1056
1057 fn ahci_port_start(port: ptr<AHCIPortRegs>) {
1058 while ((*port).cmd & 0x8000) != 0 {}
1059 (*port).cmd |= 0x0010;
1060 (*port).cmd |= 0x0001;
1061 }
1062
1063 fn ahci_port_stop(port: ptr<AHCIPortRegs>) {
1064 (*port).cmd &= !0x0001;
1065 (*port).cmd &= !0x0010;
1066 while ((*port).cmd & 0x4000) != 0 || ((*port).cmd & 0x8000) != 0 {}
1067 }
1068
1069 fn ahci_init_port(port: ptr<AHCIPortRegs>) {
1070 ahci_port_stop(port);
1071 let clb_phys = pmm_alloc_block();
1072 let fb_phys = pmm_alloc_block();
1073 let ctba_phys = pmm_alloc_block();
1074
1075 (*port).clb = clb_phys;
1076 (*port).fb = fb_phys;
1077
1078 let cmd_header = clb_phys as ptr<AHCICmdHeader>;
1079 memset(cmd_header as ptr<u8>, 0, 1024);
1080 memset(fb_phys as ptr<u8>, 0, 256);
1081 memset(ctba_phys as ptr<u8>, 0, PAGE_SIZE);
1082
1083 (*cmd_header).prdtl = 1;
1084 (*cmd_header).ctba = ctba_phys;
1085
1086 ahci_port_start(port);
1087 }
1088
1089 fn ahci_init_controller(bar5: u64) {
1090 global_ahci_hba = bar5 as ptr<AHCIHBARegs>;
1091 (*global_ahci_hba).ghc |= 0x80000000;
1092
1093 for i in 0..32 {
1094 let pi = (*global_ahci_hba).pi;
1095 if (pi & (1 << i)) != 0 {
1096 let port = &((*global_ahci_hba).ports[i as usize]) as ptr<AHCIPortRegs>;
1097 let ssts = (*port).ssts;
1098 let ipm = (ssts >> 8) & 0x0F;
1099 let det = ssts & 0x0F;
1100 let sig = (*port).sig;
1101
1102 if det == 3 && ipm == 1 {
1103 if sig == 0x00000101 {
1104 ahci_init_port(port);
1105 }
1106 }
1107 }
1108 }
1109 }
1110
1111 struct NVMeBarRegs {
1112 cap: u64,
1113 vs: u32,
1114 intms: u32,
1115 intmc: u32,
1116 cc: u32,
1117 csts: u32,
1118 nssr: u32,
1119 aqa: u32,
1120 asq: u64,
1121 acq: u64,
1122 cmbloc: u32,
1123 cmbsz: u32,
1124 bpinfo: u32,
1125 bprsel: u32,
1126 bpmbl: u64,
1127 cmbmsc: u64,
1128 cmbsts: u32,
1129 }
1130
1131 struct NVMeCmd {
1132 cdw0: u32,
1133 nsid: u32,
1134 rsv2: u64,
1135 mptr: u64,
1136 dptr1: u64,
1137 dptr2: u64,
1138 cdw10: u32,
1139 cdw11: u32,
1140 cdw12: u32,
1141 cdw13: u32,
1142 cdw14: u32,
1143 cdw15: u32,
1144 }
1145
1146 struct NVMeCpl {
1147 cdw0: u32,
1148 rsv1: u32,
1149 sqhd: u16,
1150 sqid: u16,
1151 cid: u16,
1152 status: u16,
1153 }
1154
1155 let mut global_nvme_bar: ptr<NVMeBarRegs>;
1156 let mut nvme_admin_sq: ptr<NVMeCmd>;
1157 let mut nvme_admin_cq: ptr<NVMeCpl>;
1158 let mut nvme_sq_tail: u32 = 0;
1159 let mut nvme_cq_head: u32 = 0;
1160 let mut nvme_cq_phase: u16 = 1;
1161
1162 fn nvme_submit_cmd(cmd: ptr<NVMeCmd>) {
1163 let mut sq_ptr = nvme_admin_sq as u64 + (nvme_sq_tail as u64 * sizeof(NVMeCmd) as u64);
1164 memcpy(sq_ptr as ptr<u8>, cmd as ptr<u8>, sizeof(NVMeCmd) as u64);
1165 nvme_sq_tail = (nvme_sq_tail + 1) % 64;
1166 let doorbell = (global_nvme_bar as u64 + 0x1000) as ptr<u32>;
1167 *doorbell = nvme_sq_tail;
1168 }
1169
1170 fn nvme_poll_cq() -> ptr<NVMeCpl> {
1171 let mut cq_ptr = (nvme_admin_cq as u64 + (nvme_cq_head as u64 * sizeof(NVMeCpl) as u64)) as ptr<NVMeCpl>;
1172 while ((*cq_ptr).status & 0x01) != nvme_cq_phase {
1173 cpu_pause();
1174 }
1175 nvme_cq_head = (nvme_cq_head + 1) % 64;
1176 if nvme_cq_head == 0 {
1177 nvme_cq_phase = nvme_cq_phase ^ 1;
1178 }
1179 let doorbell = (global_nvme_bar as u64 + 0x1004) as ptr<u32>;
1180 *doorbell = nvme_cq_head;
1181 return cq_ptr;
1182 }
1183
1184 fn nvme_init_controller(bar0: u64) {
1185 global_nvme_bar = bar0 as ptr<NVMeBarRegs>;
1186 (*global_nvme_bar).cc &= 0xFFFFFFFE;
1187 while ((*global_nvme_bar).csts & 1) != 0 { }
1188 nvme_admin_sq = pmm_alloc_blocks(1) as ptr<NVMeCmd>;
1189 nvme_admin_cq = pmm_alloc_blocks(1) as ptr<NVMeCpl>;
1190 memset(nvme_admin_sq as ptr<u8>, 0, PAGE_SIZE);
1191 memset(nvme_admin_cq as ptr<u8>, 0, PAGE_SIZE);
1192 (*global_nvme_bar).aqa = 0x003F003F;
1193 (*global_nvme_bar).asq = nvme_admin_sq as u64;
1194 (*global_nvme_bar).acq = nvme_admin_cq as u64;
1195 let iocqes = 4;
1196 let iosqes = 6;
1197 (*global_nvme_bar).cc = (iocqes << 20) | (iosqes << 16) | 0x00460001;
1198 while ((*global_nvme_bar).csts & 1) == 0 { }
1199 }
1200
1201 struct XHCICapRegs {
1202 caplength: u8,
1203 rsvd: u8,
1204 hciversion: u16,
1205 hcsparams1: u32,
1206 hcsparams2: u32,
1207 hcsparams3: u32,
1208 hccparams1: u32,
1209 dboff: u32,
1210 rtsoff: u32,
1211 hccparams2: u32,
1212 }
1213
1214 struct XHCIOpRegs {
1215 usbcmd: u32,
1216 usbsts: u32,
1217 pagesize: u32,
1218 rsvd1: [u32; 2],
1219 dnctrl: u32,
1220 crcr: u64,
1221 rsvd2: [u32; 4],
1222 dcbaap: u64,
1223 config: u32,
1224 }
1225
1226 struct XHCIPortRegs {
1227 portsc: u32,
1228 portpmsc: u32,
1229 portli: u32,
1230 porthlpmc: u32,
1231 }
1232
1233 struct XHCITrb {
1234 param: u64,
1235 status: u32,
1236 control: u32,
1237 }
1238
1239 let mut global_xhci_cap: ptr<XHCICapRegs>;
1240 let mut global_xhci_op: ptr<XHCIOpRegs>;
1241 let mut xhci_cmd_ring: ptr<XHCITrb>;
1242 let mut xhci_dcbaa: ptr<u64>;
1243
1244 fn xhci_reset() {
1245 (*global_xhci_op).usbcmd &= 0xFFFFFFFE;
1246 while ((*global_xhci_op).usbsts & 1) == 0 { }
1247 (*global_xhci_op).usbcmd |= 2;
1248 while ((*global_xhci_op).usbcmd & 2) != 0 { }
1249 while ((*global_xhci_op).usbsts & (1 << 11)) != 0 { }
1250 }
1251
1252 fn xhci_init_controller(bar0: u64) {
1253 global_xhci_cap = bar0 as ptr<XHCICapRegs>;
1254 global_xhci_op = (bar0 + (*global_xhci_cap).caplength as u64) as ptr<XHCIOpRegs>;
1255 xhci_reset();
1256 let max_slots = (*global_xhci_cap).hcsparams1 & 0xFF;
1257 (*global_xhci_op).config = max_slots;
1258 xhci_dcbaa = pmm_alloc_blocks(1) as ptr<u64>;
1259 memset(xhci_dcbaa as ptr<u8>, 0, PAGE_SIZE);
1260 (*global_xhci_op).dcbaap = xhci_dcbaa as u64;
1261 xhci_cmd_ring = pmm_alloc_blocks(1) as ptr<XHCITrb>;
1262 memset(xhci_cmd_ring as ptr<u8>, 0, PAGE_SIZE);
1263 (*global_xhci_op).crcr = (xhci_cmd_ring as u64) | 1;
1264 (*global_xhci_op).usbcmd |= 1;
1265 while ((*global_xhci_op).usbsts & 1) != 0 { }
1266 }
1267
1268 let mut rtl_iobase: u64 = 0;
1269 let mut rtl_rx_buffer: ptr<u8>;
1270 let mut rtl_tx_buffers: [ptr<u8>; 4];
1271 let mut rtl_tx_idx: u8 = 0;
1272
1273 fn rtl_outb(offset: u16, data: u8) { outb((rtl_iobase + offset as u64) as u16, data); }
1274 fn rtl_outw(offset: u16, data: u16) { outw((rtl_iobase + offset as u64) as u16, data); }
1275 fn rtl_outl(offset: u16, data: u32) { outl((rtl_iobase + offset as u64) as u16, data); }
1276 fn rtl_inb(offset: u16) -> u8 { return inb((rtl_iobase + offset as u64) as u16); }
1277 fn rtl_inw(offset: u16) -> u16 { return inw((rtl_iobase + offset as u64) as u16); }
1278 fn rtl_inl(offset: u16) -> u32 { return inl((rtl_iobase + offset as u64) as u16); }
1279
1280 fn rtl8139_init(bar0: u64) {
1281 rtl_iobase = bar0 & 0xFFFFFFFFFFFFFFFC;
1282 rtl_outb(0x52, 0);
1283 rtl_outb(0x37, 0x10);
1284 while (rtl_inb(0x37) & 0x10) != 0 { }
1285 rtl_rx_buffer = pmm_alloc_blocks(3) as ptr<u8>;
1286 memset(rtl_rx_buffer, 0, 8192 + 16 + 1500);
1287 rtl_outl(0x30, rtl_rx_buffer as u64 as u32);
1288 for i in 0..4 {
1289 rtl_tx_buffers[i] = pmm_alloc_blocks(1) as ptr<u8>;
1290 memset(rtl_tx_buffers[i], 0, PAGE_SIZE);
1291 }
1292 rtl_outw(0x3C, 0x0005);
1293 let rx_config: u32 = 0x0000000F | 0x00000080;
1294 rtl_outl(0x44, rx_config);
1295 rtl_outb(0x37, 0x0C);
1296 }
1297
1298 fn rtl8139_send(packet: ptr<u8>, length: u32) {
1299 let tx_addr = rtl_tx_buffers[rtl_tx_idx as usize];
1300 memcpy(tx_addr, packet, length as u64);
1301 let port = 0x20 + (rtl_tx_idx as u16 * 4);
1302 rtl_outl(port, tx_addr as u64 as u32);
1303 let status_port = 0x10 + (rtl_tx_idx as u16 * 4);
1304 rtl_outl(status_port, length);
1305 rtl_tx_idx = (rtl_tx_idx + 1) % 4;
1306 }
1307
1308 struct MacAddr { addr: [u8; 6] }
1309 struct Ipv4Addr { addr: [u8; 4] }
1310
1311 struct EthernetHeader {
1312 dest_mac: MacAddr,
1313 src_mac: MacAddr,
1314 ethertype: u16,
1315 }
1316
1317 struct ArpHeader {
1318 hw_type: u16,
1319 proto_type: u16,
1320 hw_len: u8,
1321 proto_len: u8,
1322 opcode: u16,
1323 sender_mac: MacAddr,
1324 sender_ip: Ipv4Addr,
1325 target_mac: MacAddr,
1326 target_ip: Ipv4Addr,
1327 }
1328
1329 struct Ipv4Header {
1330 ihl_version: u8,
1331 tos: u8,
1332 total_length: u16,
1333 id: u16,
1334 flags_frag: u16,
1335 ttl: u8,
1336 protocol: u8,
1337 checksum: u16,
1338 src_ip: Ipv4Addr,
1339 dest_ip: Ipv4Addr,
1340 }
1341
1342 struct UdpHeader {
1343 src_port: u16,
1344 dest_port: u16,
1345 length: u16,
1346 checksum: u16,
1347 }
1348
1349 struct TcpHeader {
1350 src_port: u16,
1351 dest_port: u16,
1352 seq_num: u32,
1353 ack_num: u32,
1354 data_offset_flags: u16,
1355 window_size: u16,
1356 checksum: u16,
1357 urgent_ptr: u16,
1358 }
1359
1360 let mut system_mac: MacAddr;
1361 let mut system_ip: Ipv4Addr;
1362
1363 fn htons(hostshort: u16) -> u16 {
1364 return (hostshort >> 8) | (hostshort << 8);
1365 }
1366
1367 fn htonl(hostlong: u32) -> u32 {
1368 return ((hostlong & 0xFF) << 24) | ((hostlong & 0xFF00) << 8) | ((hostlong & 0xFF0000) >> 8) | ((hostlong >> 24) & 0xFF);
1369 }
1370
1371 fn calculate_checksum(data: ptr<u8>, length: u32) -> u16 {
1372 let mut sum: u32 = 0;
1373 let mut ptr16 = data as ptr<u16>;
1374 let mut len = length;
1375 while len > 1 {
1376 sum = sum + *ptr16 as u32;
1377 ptr16 = (ptr16 as u64 + 2) as ptr<u16>;
1378 len = len - 2;
1379 }
1380 if len == 1 {
1381 let mut last_byte: u16 = 0;
1382 *(last_byte as u64 as ptr<u8>) = *(ptr16 as ptr<u8>);
1383 sum = sum + last_byte as u32;
1384 }
1385 while (sum >> 16) != 0 {
1386 sum = (sum & 0xFFFF) + (sum >> 16);
1387 }
1388 return (!sum) as u16;
1389 }
1390
1391 fn arp_send_request(target_ip: Ipv4Addr) {
1392 let packet_size = sizeof(EthernetHeader) as u64 + sizeof(ArpHeader) as u64;
1393 let packet = pmm_alloc_blocks(1) as ptr<u8>;
1394 let eth = packet as ptr<EthernetHeader>;
1395 for i in 0..6 { (*eth).dest_mac.addr[i] = 0xFF; }
1396 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
1397 (*eth).ethertype = htons(0x0806);
1398
1399 let arp = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<ArpHeader>;
1400 (*arp).hw_type = htons(0x0001);
1401 (*arp).proto_type = htons(0x0800);
1402 (*arp).hw_len = 6;
1403 (*arp).proto_len = 4;
1404 (*arp).opcode = htons(0x0001);
1405 for i in 0..6 { (*arp).sender_mac.addr[i] = system_mac.addr[i]; }
1406 for i in 0..4 { (*arp).sender_ip.addr[i] = system_ip.addr[i]; }
1407 for i in 0..6 { (*arp).target_mac.addr[i] = 0x00; }
1408 for i in 0..4 { (*arp).target_ip.addr[i] = target_ip.addr[i]; }
1409
1410 rtl8139_send(packet, packet_size as u32);
1411 pmm_free_block(packet as u64);
1412 }
1413
1414 struct CpuContext {
1415 r15: u64, r14: u64, r13: u64, r12: u64,
1416 r11: u64, r10: u64, r9: u64, r8: u64,
1417 rdi: u64, rsi: u64, rbp: u64, rbx: u64,
1418 rdx: u64, rcx: u64, rax: u64,
1419 rip: u64, cs: u64, rflags: u64, rsp: u64, ss: u64,
1420 }
1421
1422 struct ProcessControlBlock {
1423 pid: u64,
1424 cr3_phys: u64,
1425 context: ptr<CpuContext>,
1426 state: u8,
1427 priority: u8,
1428 time_slice: u64,
1429 next: ptr<ProcessControlBlock>,
1430 }
1431
1432 let mut current_process: ptr<ProcessControlBlock>;
1433 let mut process_queue: ptr<ProcessControlBlock>;
1434 let mut global_pid_counter: u64 = 1000;
1435
1436 fn create_process(entry_point: u64, is_kernel: bool) -> ptr<ProcessControlBlock> {
1437 let pcb = pmm_alloc_blocks(1) as ptr<ProcessControlBlock>;
1438 memset(pcb as ptr<u8>, 0, sizeof(ProcessControlBlock) as u64);
1439 (*pcb).pid = global_pid_counter;
1440 global_pid_counter = global_pid_counter + 1;
1441 let stack_phys = pmm_alloc_blocks(4);
1442 let stack_top = stack_phys + (PAGE_SIZE * 4);
1443 let ctx = (stack_top - sizeof(CpuContext) as u64) as ptr<CpuContext>;
1444 memset(ctx as ptr<u8>, 0, sizeof(CpuContext) as u64);
1445 (*ctx).rip = entry_point;
1446 (*ctx).rflags = 0x202;
1447 (*ctx).rsp = stack_top;
1448 if is_kernel {
1449 (*ctx).cs = 0x08;
1450 (*ctx).ss = 0x10;
1451 (*pcb).cr3_phys = vmm_pml4 as u64;
1452 } else {
1453 (*ctx).cs = 0x1B;
1454 (*ctx).ss = 0x23;
1455 (*pcb).cr3_phys = pmm_alloc_blocks(1);
1456 memset((*pcb).cr3_phys as ptr<u8>, 0, PAGE_SIZE);
1457 }
1458 (*pcb).context = ctx;
1459 (*pcb).state = 1;
1460 (*pcb).time_slice = 10;
1461 (*pcb).next = process_queue;
1462 process_queue = pcb;
1463 return pcb;
1464 }
1465
1466 fn switch_context(next: ptr<ProcessControlBlock>) {
1467 let prev = current_process;
1468 current_process = next;
1469 asm {
1470 "mov rsp, %0\n"
1471 "mov cr3, %1\n"
1472 "pop r15\n pop r14\n pop r13\n pop r12\n"
1473 "pop r11\n pop r10\n pop r9\n pop r8\n"
1474 "pop rdi\n pop rsi\n pop rbp\n pop rbx\n"
1475 "pop rdx\n pop rcx\n pop rax\n"
1476 "iretq"
1477 in "%0" = (*next).context;
1478 in "%1" = (*next).cr3_phys;
1479 }
1480 }
1481
1482 fn scheduler_tick() {
1483 if current_process == 0 as ptr<ProcessControlBlock> {
1484 if process_queue != 0 as ptr<ProcessControlBlock> {
1485 switch_context(process_queue);
1486 }
1487 return;
1488 }
1489 (*current_process).time_slice = (*current_process).time_slice - 1;
1490 if (*current_process).time_slice == 0 {
1491 (*current_process).time_slice = 10;
1492 let mut next = (*current_process).next;
1493 if next == 0 as ptr<ProcessControlBlock> {
1494 next = process_queue;
1495 }
1496 if next != current_process {
1497 switch_context(next);
1498 }
1499 }
1500 }
1501
1502 struct VfsStat {
1503 size: u64,
1504 inode: u64,
1505 flags: u32,
1506 uid: u32,
1507 gid: u32,
1508 }
1509
1510 struct VfsNode {
1511 name: [u8; 128],
1512 mask: u32,
1513 uid: u32,
1514 gid: u32,
1515 flags: u32,
1516 inode: u64,
1517 length: u64,
1518 read_fn: u64,
1519 write_fn: u64,
1520 open_fn: u64,
1521 close_fn: u64,
1522 readdir_fn: u64,
1523 finddir_fn: u64,
1524 ptr: u64,
1525 parent: ptr<VfsNode>,
1526 children: ptr<VfsNode>,
1527 next: ptr<VfsNode>,
1528 }
1529
1530 struct FileDescriptor {
1531 node: ptr<VfsNode>,
1532 offset: u64,
1533 flags: u32,
1534 }
1535
1536 let mut global_vfs_root: ptr<VfsNode>;
1537 let mut next_inode: u64 = 1;
1538
1539 fn vfs_init_system() {
1540 global_vfs_root = pmm_alloc_blocks(1) as ptr<VfsNode>;
1541 memset(global_vfs_root as ptr<u8>, 0, sizeof(VfsNode) as u64);
1542 strcpy(&((*global_vfs_root).name[0]), "/" as ptr<u8>);
1543 (*global_vfs_root).flags = 0x07;
1544 (*global_vfs_root).inode = 0;
1545 }
1546
1547 fn vfs_create_node(parent: ptr<VfsNode>, name: ptr<u8>, flags: u32) -> ptr<VfsNode> {
1548 let node = pmm_alloc_blocks(1) as ptr<VfsNode>;
1549 memset(node as ptr<u8>, 0, sizeof(VfsNode) as u64);
1550 strcpy(&((*node).name[0]), name);
1551 (*node).flags = flags;
1552 (*node).inode = next_inode;
1553 next_inode = next_inode + 1;
1554 (*node).parent = parent;
1555 if (*parent).children == 0 as ptr<VfsNode> {
1556 (*parent).children = node;
1557 } else {
1558 let mut curr = (*parent).children;
1559 while (*curr).next != 0 as ptr<VfsNode> {
1560 curr = (*curr).next;
1561 }
1562 (*curr).next = node;
1563 }
1564 return node;
1565 }
1566
1567 fn vfs_find_child(parent: ptr<VfsNode>, name: ptr<u8>) -> ptr<VfsNode> {
1568 let mut curr = (*parent).children;
1569 while curr != 0 as ptr<VfsNode> {
1570 if strcmp(&((*curr).name[0]), name) == 0 {
1571 return curr;
1572 }
1573 curr = (*curr).next;
1574 }
1575 return 0 as ptr<VfsNode>;
1576 }
1577
1578 fn vfs_read(fd: ptr<FileDescriptor>, buffer: ptr<u8>, size: u64) -> u64 {
1579 if (*fd).node == 0 as ptr<VfsNode> { return 0; }
1580 if ((*(*fd).node).flags & 0x07) != 0 { return 0; }
1581 let mut read_sz = size;
1582 if (*fd).offset + size > (*(*fd).node).length {
1583 read_sz = (*(*fd).node).length - (*fd).offset;
1584 }
1585 let data_ptr = (*(*fd).node).ptr as ptr<u8>;
1586 memcpy(buffer, (data_ptr as u64 + (*fd).offset) as ptr<u8>, read_sz);
1587 (*fd).offset = (*fd).offset + read_sz;
1588 return read_sz;
1589 }
1590
1591 fn vfs_write(fd: ptr<FileDescriptor>, buffer: ptr<u8>, size: u64) -> u64 {
1592 if (*fd).node == 0 as ptr<VfsNode> { return 0; }
1593 if ((*(*fd).node).flags & 0x07) != 0 { return 0; }
1594 let data_ptr = (*(*fd).node).ptr as ptr<u8>;
1595 memcpy((data_ptr as u64 + (*fd).offset) as ptr<u8>, buffer, size);
1596 (*fd).offset = (*fd).offset + size;
1597 if (*fd).offset > (*(*fd).node).length {
1598 (*(*fd).node).length = (*fd).offset;
1599 }
1600 return size;
1601 }
1602
1603 let mut sha256_k: [u32; 64] = [
1604 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1605 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1606 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1607 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1608 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1609 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1610 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1611 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1612 ];
1613
1614 fn rotr32(x: u32, n: u32) -> u32 { return (x >> n) | (x << (32 - n)); }
1615 fn ch(x: u32, y: u32, z: u32) -> u32 { return (x & y) ^ (!x & z); }
1616 fn maj(x: u32, y: u32, z: u32) -> u32 { return (x & y) ^ (x & z) ^ (y & z); }
1617 fn sig0(x: u32) -> u32 { return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); }
1618 fn sig1(x: u32) -> u32 { return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); }
1619 fn ep0(x: u32) -> u32 { return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3); }
1620 fn ep1(x: u32) -> u32 { return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10); }
1621
1622 struct Sha256Ctx {
1623 state: [u32; 8],
1624 count: [u32; 2],
1625 buffer: [u8; 64],
1626 }
1627
1628 fn sha256_transform(ctx: ptr<Sha256Ctx>, data: ptr<u8>) {
1629 let mut w: [u32; 64];
1630 for i in 0..16 {
1631 w[i] = ((*(data + i as u64 * 4) as u32) << 24) | ((*(data + i as u64 * 4 + 1) as u32) << 16) | ((*(data + i as u64 * 4 + 2) as u32) << 8) | (*(data + i as u64 * 4 + 3) as u32);
1632 }
1633 for i in 16..64 {
1634 w[i] = ep1(w[i - 2]) + w[i - 7] + ep0(w[i - 15]) + w[i - 16];
1635 }
1636 let mut a = (*ctx).state[0]; let mut b = (*ctx).state[1]; let mut c = (*ctx).state[2]; let mut d = (*ctx).state[3];
1637 let mut e = (*ctx).state[4]; let mut f = (*ctx).state[5]; let mut g = (*ctx).state[6]; let mut h = (*ctx).state[7];
1638 for i in 0..64 {
1639 let t1 = h + sig1(e) + ch(e, f, g) + sha256_k[i] + w[i];
1640 let t2 = sig0(a) + maj(a, b, c);
1641 h = g; g = f; f = e; e = d + t1;
1642 d = c; c = b; b = a; a = t1 + t2;
1643 }
1644 (*ctx).state[0] += a; (*ctx).state[1] += b; (*ctx).state[2] += c; (*ctx).state[3] += d;
1645 (*ctx).state[4] += e; (*ctx).state[5] += f; (*ctx).state[6] += g; (*ctx).state[7] += h;
1646 }
1647
1648 fn sha256_init(ctx: ptr<Sha256Ctx>) {
1649 (*ctx).count[0] = 0; (*ctx).count[1] = 0;
1650 (*ctx).state[0] = 0x6a09e667; (*ctx).state[1] = 0xbb67ae85;
1651 (*ctx).state[2] = 0x3c6ef372; (*ctx).state[3] = 0xa54ff53a;
1652 (*ctx).state[4] = 0x510e527f; (*ctx).state[5] = 0x9b05688c;
1653 (*ctx).state[6] = 0x1f83d9ab; (*ctx).state[7] = 0x5be0cd19;
1654 }
1655
1656 let mut aes_sbox: [u8; 256] = [
1657 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
1658 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
1659 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
1660 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
1661 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
1662 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
1663 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
1664 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
1665 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
1666 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
1667 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
1668 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
1669 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
1670 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
1671 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
1672 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
1673 ];
1674
1675 fn sub_word(w: u32) -> u32 {
1676 let b0 = aes_sbox[(w & 0xFF) as usize] as u32;
1677 let b1 = aes_sbox[((w >> 8) & 0xFF) as usize] as u32;
1678 let b2 = aes_sbox[((w >> 16) & 0xFF) as usize] as u32;
1679 let b3 = aes_sbox[((w >> 24) & 0xFF) as usize] as u32;
1680 return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
1681 }
1682
1683 struct CompositorWindow {
1684 id: u64,
1685 x: u32,
1686 y: u32,
1687 width: u32,
1688 height: u32,
1689 z_index: u32,
1690 flags: u32,
1691 title: [u8; 64],
1692 buffer_phys: u64,
1693 next: ptr<CompositorWindow>,
1694 }
1695
1696 let mut comp_root_window: ptr<CompositorWindow>;
1697 let mut comp_active_window: ptr<CompositorWindow>;
1698 let mut comp_back_buffer: ptr<u32>;
1699 let mut comp_width: u32 = 1920;
1700 let mut comp_height: u32 = 1080;
1701 let mut comp_next_id: u64 = 1;
1702
1703 fn comp_init(fb_base: u64, w: u32, h: u32) {
1704 comp_width = w;
1705 comp_height = h;
1706 comp_back_buffer = pmm_alloc_blocks((w * h * 4) / PAGE_SIZE + 1) as ptr<u32>;
1707 memset(comp_back_buffer as ptr<u8>, 0, (w * h * 4) as u64);
1708 fb_ptr = fb_base as ptr<u32>;
1709 }
1710
1711 fn comp_create_window(x: u32, y: u32, w: u32, h: u32, title: ptr<u8>) -> ptr<CompositorWindow> {
1712 let win = pmm_alloc_blocks(1) as ptr<CompositorWindow>;
1713 memset(win as ptr<u8>, 0, sizeof(CompositorWindow) as u64);
1714 (*win).id = comp_next_id;
1715 comp_next_id = comp_next_id + 1;
1716 (*win).x = x;
1717 (*win).y = y;
1718 (*win).width = w;
1719 (*win).height = h;
1720 (*win).z_index = 100;
1721 strcpy(&((*win).title[0]), title);
1722 let buf_sz = w * h * 4;
1723 (*win).buffer_phys = pmm_alloc_blocks(buf_sz as u64 / PAGE_SIZE + 1);
1724 memset((*win).buffer_phys as ptr<u8>, 0xFF, buf_sz as u64);
1725 (*win).next = comp_root_window;
1726 comp_root_window = win;
1727 comp_active_window = win;
1728 return win;
1729 }
1730
1731 fn comp_draw_rect(win: ptr<CompositorWindow>, x: u32, y: u32, w: u32, h: u32, color: u32) {
1732 let buf = (*win).buffer_phys as ptr<u32>;
1733 for i in 0..h {
1734 for j in 0..w {
1735 if (x + j) < (*win).width && (y + i) < (*win).height {
1736 *(buf + ((y + i) * (*win).width + (x + j)) as u64) = color;
1737 }
1738 }
1739 }
1740 }
1741
1742 fn comp_render() {
1743 let bg_color = 0x2c3e50;
1744 for i in 0..(comp_width * comp_height) {
1745 *(comp_back_buffer + i as u64) = bg_color;
1746 }
1747 let mut curr = comp_root_window;
1748 while curr != 0 as ptr<CompositorWindow> {
1749 let buf = (*curr).buffer_phys as ptr<u32>;
1750 for i in 0..(*curr).height {
1751 for j in 0..(*curr).width {
1752 let screen_y = (*curr).y + i;
1753 let screen_x = (*curr).x + j;
1754 if screen_x < comp_width && screen_y < comp_height {
1755 let pixel = *(buf + (i * (*curr).width + j) as u64);
1756 *(comp_back_buffer + (screen_y * comp_width + screen_x) as u64) = pixel;
1757 }
1758 }
1759 }
1760 curr = (*curr).next;
1761 }
1762 memcpy(fb_ptr as ptr<u8>, comp_back_buffer as ptr<u8>, (comp_width * comp_height * 4) as u64);
1763 }
1764
1765 const ELF_MAGIC: u32 = 0x464C457F;
1766
1767 struct Elf64_Ehdr {
1768 e_ident: [u8; 16],
1769 e_type: u16,
1770 e_machine: u16,
1771 e_version: u32,
1772 e_entry: u64,
1773 e_phoff: u64,
1774 e_shoff: u64,
1775 e_flags: u32,
1776 e_ehsize: u16,
1777 e_phentsize: u16,
1778 e_phnum: u16,
1779 e_shentsize: u16,
1780 e_shnum: u16,
1781 e_shstrndx: u16,
1782 }
1783
1784 struct Elf64_Phdr {
1785 p_type: u32,
1786 p_flags: u32,
1787 p_offset: u64,
1788 p_vaddr: u64,
1789 p_paddr: u64,
1790 p_filesz: u64,
1791 p_memsz: u64,
1792 p_align: u64,
1793 }
1794
1795 struct AegisPermissionMatrix {
1796 uid: u32,
1797 gid: u32,
1798 capabilities: u64,
1799 network_access: u8,
1800 fs_access: u8,
1801 hw_access: u8,
1802 max_memory: u64,
1803 }
1804
1805 let mut global_aegis_matrix: [AegisPermissionMatrix; 1024];
1806 let mut aegis_matrix_count: u32 = 0;
1807
1808 fn aegis_register_process(pid: u64, uid: u32, gid: u32, caps: u64) {
1809 let mut idx = aegis_matrix_count;
1810 global_aegis_matrix[idx as usize].uid = uid;
1811 global_aegis_matrix[idx as usize].gid = gid;
1812 global_aegis_matrix[idx as usize].capabilities = caps;
1813 global_aegis_matrix[idx as usize].network_access = 1;
1814 global_aegis_matrix[idx as usize].fs_access = 1;
1815 global_aegis_matrix[idx as usize].hw_access = 0;
1816 global_aegis_matrix[idx as usize].max_memory = 0x10000000;
1817 aegis_matrix_count = aegis_matrix_count + 1;
1818 }
1819
1820 fn aegis_verify_execution(node: ptr<VfsNode>, uid: u32) -> bool {
1821 if (*node).uid != uid && uid != 0 {
1822 if ((*node).flags & 0x01) == 0 {
1823 return false;
1824 }
1825 }
1826 return true;
1827 }
1828
1829 fn elf_check_header(hdr: ptr<Elf64_Ehdr>) -> bool {
1830 let magic = *(hdr as ptr<u32>);
1831 if magic != ELF_MAGIC { return false; }
1832 if (*hdr).e_ident[4] != 2 { return false; }
1833 if (*hdr).e_ident[5] != 1 { return false; }
1834 if (*hdr).e_machine != 62 { return false; }
1835 return true;
1836 }
1837
1838 fn elf_load_segment(phdr: ptr<Elf64_Phdr>, fd: ptr<FileDescriptor>, cr3: u64) {
1839 let mut vaddr = (*phdr).p_vaddr;
1840 let memsz = (*phdr).p_memsz;
1841 let filesz = (*phdr).p_filesz;
1842 let offset = (*phdr).p_offset;
1843
1844 let pages = (memsz + PAGE_SIZE - 1) / PAGE_SIZE;
1845 let mut current_vaddr = vaddr & !(PAGE_SIZE - 1);
1846
1847 for i in 0..pages {
1848 let phys = pmm_alloc_blocks(1);
1849 memset(phys as ptr<u8>, 0, PAGE_SIZE);
1850 let flags = 0x07;
1851 vmm_map_page(phys, current_vaddr, flags);
1852 current_vaddr = current_vaddr + PAGE_SIZE;
1853 }
1854
1855 (*fd).offset = offset;
1856 let mut buffer = vaddr as ptr<u8>;
1857 vfs_read(fd, buffer, filesz);
1858 }
1859
1860 fn execve_ring3(path: ptr<u8>, uid: u32, gid: u32) -> u64 {
1861 let root = global_vfs_root;
1862 let mut curr = root;
1863 let mut node = vfs_find_child(curr, path);
1864 if node == 0 as ptr<VfsNode> { return 0; }
1865
1866 if !aegis_verify_execution(node, uid) { return 0; }
1867
1868 let mut fd: FileDescriptor;
1869 fd.node = node;
1870 fd.offset = 0;
1871 fd.flags = 0;
1872
1873 let mut hdr_buf: [u8; 64];
1874 vfs_read(&fd, &hdr_buf[0] as ptr<u8>, 64);
1875 let ehdr = &hdr_buf[0] as ptr<Elf64_Ehdr>;
1876
1877 if !elf_check_header(ehdr) { return 0; }
1878
1879 let process = create_process((*ehdr).e_entry, false);
1880 aegis_register_process((*process).pid, uid, gid, 0xFFFFFFFF);
1881
1882 let phdr_size = (*ehdr).e_phnum as u64 * (*ehdr).e_phentsize as u64;
1883 let phdr_buf = pmm_alloc_blocks((phdr_size / PAGE_SIZE) + 1) as ptr<u8>;
1884
1885 fd.offset = (*ehdr).e_phoff;
1886 vfs_read(&fd, phdr_buf, phdr_size);
1887
1888 for i in 0..(*ehdr).e_phnum {
1889 let phdr = (phdr_buf as u64 + (i as u64 * (*ehdr).e_phentsize as u64)) as ptr<Elf64_Phdr>;
1890 if (*phdr).p_type == 1 {
1891 elf_load_segment(phdr, &fd, (*process).cr3_phys);
1892 }
1893 }
1894
1895 pmm_free_blocks(phdr_buf as u64, (phdr_size / PAGE_SIZE) + 1);
1896 return (*process).pid;
1897 }
1898
1899 struct IpcMessage {
1900 sender_pid: u64,
1901 target_pid: u64,
1902 msg_type: u32,
1903 length: u32,
1904 data: [u8; 112],
1905 next: ptr<IpcMessage>,
1906 }
1907
1908 struct IpcQueue {
1909 owner_pid: u64,
1910 head: ptr<IpcMessage>,
1911 tail: ptr<IpcMessage>,
1912 msg_count: u32,
1913 lock: Spinlock,
1914 }
1915
1916 let mut global_ipc_queues: [IpcQueue; 1024];
1917 let mut ipc_queue_count: u32 = 0;
1918
1919 fn ipc_create_queue(pid: u64) {
1920 let mut q = &global_ipc_queues[ipc_queue_count as usize];
1921 (*q).owner_pid = pid;
1922 (*q).head = 0 as ptr<IpcMessage>;
1923 (*q).tail = 0 as ptr<IpcMessage>;
1924 (*q).msg_count = 0;
1925 spin_init(&((*q).lock));
1926 ipc_queue_count = ipc_queue_count + 1;
1927 }
1928
1929 fn ipc_send_message(target_pid: u64, sender_pid: u64, mtype: u32, data: ptr<u8>, len: u32) -> u32 {
1930 let mut target_q = 0 as ptr<IpcQueue>;
1931 for i in 0..ipc_queue_count {
1932 if global_ipc_queues[i as usize].owner_pid == target_pid {
1933 target_q = &global_ipc_queues[i as usize];
1934 }
1935 }
1936 if target_q == 0 as ptr<IpcQueue> { return 1; }
1937
1938 let msg = pmm_alloc_blocks(1) as ptr<IpcMessage>;
1939 memset(msg as ptr<u8>, 0, sizeof(IpcMessage) as u64);
1940 (*msg).sender_pid = sender_pid;
1941 (*msg).target_pid = target_pid;
1942 (*msg).msg_type = mtype;
1943 let mut c_len = len;
1944 if c_len > 112 { c_len = 112; }
1945 (*msg).length = c_len;
1946 memcpy(&((*msg).data[0]) as ptr<u8>, data, c_len as u64);
1947 (*msg).next = 0 as ptr<IpcMessage>;
1948
1949 spin_lock(&((*target_q).lock));
1950 if (*target_q).tail == 0 as ptr<IpcMessage> {
1951 (*target_q).head = msg;
1952 (*target_q).tail = msg;
1953 } else {
1954 (*((*target_q).tail)).next = msg;
1955 (*target_q).tail = msg;
1956 }
1957 (*target_q).msg_count = (*target_q).msg_count + 1;
1958 spin_unlock(&((*target_q).lock));
1959 return 0;
1960 }
1961
1962 fn ipc_receive_message(pid: u64, out_msg: ptr<IpcMessage>) -> u32 {
1963 let mut my_q = 0 as ptr<IpcQueue>;
1964 for i in 0..ipc_queue_count {
1965 if global_ipc_queues[i as usize].owner_pid == pid {
1966 my_q = &global_ipc_queues[i as usize];
1967 }
1968 }
1969 if my_q == 0 as ptr<IpcQueue> { return 1; }
1970
1971 spin_lock(&((*my_q).lock));
1972 if (*my_q).head == 0 as ptr<IpcMessage> {
1973 spin_unlock(&((*my_q).lock));
1974 return 2;
1975 }
1976
1977 let msg = (*my_q).head;
1978 (*my_q).head = (*msg).next;
1979 if (*my_q).head == 0 as ptr<IpcMessage> {
1980 (*my_q).tail = 0 as ptr<IpcMessage>;
1981 }
1982 (*my_q).msg_count = (*my_q).msg_count - 1;
1983 spin_unlock(&((*my_q).lock));
1984
1985 memcpy(out_msg as ptr<u8>, msg as ptr<u8>, sizeof(IpcMessage) as u64);
1986 pmm_free_blocks(msg as u64, 1);
1987 return 0;
1988 }
1989
1990 fn sys_read_wrap(fd_ptr: u64, buf: u64, size: u64) -> u64 {
1991 let fd = fd_ptr as ptr<FileDescriptor>;
1992 return vfs_read(fd, buf as ptr<u8>, size);
1993 }
1994
1995 fn sys_write_wrap(fd_ptr: u64, buf: u64, size: u64) -> u64 {
1996 let fd = fd_ptr as ptr<FileDescriptor>;
1997 return vfs_write(fd, buf as ptr<u8>, size);
1998 }
1999
2000 fn sys_mmap(addr: u64, len: u64, prot: u64, flags: u64, fd_ptr: u64, offset: u64) -> u64 {
2001 let pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
2002 let mut vaddr = addr;
2003 if vaddr == 0 {
2004 vaddr = 0x4000000000;
2005 }
2006 let mut cur = vaddr;
2007 for i in 0..pages {
2008 let phys = pmm_alloc_blocks(1);
2009 memset(phys as ptr<u8>, 0, PAGE_SIZE);
2010 vmm_map_page(phys, cur, prot);
2011 cur = cur + PAGE_SIZE;
2012 }
2013 if fd_ptr != 0 {
2014 let fd = fd_ptr as ptr<FileDescriptor>;
2015 let old_off = (*fd).offset;
2016 (*fd).offset = offset;
2017 vfs_read(fd, vaddr as ptr<u8>, len);
2018 (*fd).offset = old_off;
2019 }
2020 return vaddr;
2021 }
2022
2023 fn syscall_handler_64_adv() {
2024 let mut rax: u64; let mut rdi: u64; let mut rsi: u64;
2025 let mut rdx: u64; let mut r10: u64; let mut r8: u64; let mut r9: u64;
2026
2027 asm { "mov %0, rax" out rax = rax; }
2028 asm { "mov %0, rdi" out rdi = rdi; }
2029 asm { "mov %0, rsi" out rsi = rsi; }
2030 asm { "mov %0, rdx" out rdx = rdx; }
2031 asm { "mov %0, r10" out r10 = r10; }
2032 asm { "mov %0, r8" out r8 = r8; }
2033 asm { "mov %0, r9" out r9 = r9; }
2034
2035 if rax == 0 {
2036 asm { "mov rax, %0" in rax = sys_read_wrap(rdi, rsi, rdx); }
2037 } else if rax == 1 {
2038 asm { "mov rax, %0" in rax = sys_write_wrap(rdi, rsi, rdx); }
2039 } else if rax == 2 {
2040 let node = vfs_find_child(global_vfs_root, rdi as ptr<u8>);
2041 if node == 0 as ptr<VfsNode> {
2042 asm { "mov rax, 0" }
2043 } else {
2044 let fd = pmm_alloc_blocks(1) as ptr<FileDescriptor>;
2045 (*fd).node = node; (*fd).offset = 0; (*fd).flags = rsi as u32;
2046 asm { "mov rax, %0" in rax = fd as u64; }
2047 }
2048 } else if rax == 3 {
2049 pmm_free_blocks(rdi, 1);
2050 asm { "mov rax, 0" }
2051 } else if rax == 9 {
2052 asm { "mov rax, %0" in rax = sys_mmap(rdi, rsi, rdx, r10, r8, r9); }
2053 } else if rax == 59 {
2054 asm { "mov rax, %0" in rax = execve_ring3(rdi as ptr<u8>, rsi as u32, rdx as u32); }
2055 } else if rax == 60 {
2056 (*current_process).state = 0;
2057 scheduler_tick();
2058 } else if rax == 100 {
2059 comp_draw_rect(rdi as ptr<CompositorWindow>, rsi as u32, rdx as u32, r10 as u32, r8 as u32, r9 as u32);
2060 asm { "mov rax, 0" }
2061 } else if rax == 200 {
2062 let ctx = rdi as ptr<Sha256Ctx>;
2063 sha256_init(ctx);
2064 sha256_transform(ctx, rsi as ptr<u8>);
2065 asm { "mov rax, 0" }
2066 } else if rax == 300 {
2067 asm { "mov rax, %0" in rax = ipc_send_message(rdi, rsi, rdx as u32, r10 as ptr<u8>, r8 as u32) as u64; }
2068 } else if rax == 301 {
2069 asm { "mov rax, %0" in rax = ipc_receive_message(rdi, rsi as ptr<IpcMessage>) as u64; }
2070 } else {
2071 asm { "mov rax, -1" }
2072 }
2073 }
2074
2075 struct CpuCoreInfo {
2076 apic_id: u8,
2077 acpi_id: u8,
2078 is_bsp: bool,
2079 is_active: bool,
2080 stack_base: u64,
2081 current_task: u64,
2082 }
2083
2084 let mut smp_cores: [CpuCoreInfo; 256];
2085 let mut smp_core_count: u32 = 0;
2086 let mut smp_bsp_id: u8 = 0;
2087 let mut smp_lock: Spinlock;
2088
2089 fn smp_register_core(apic_id: u8, acpi_id: u8, is_bsp: bool) {
2090 let idx = smp_core_count;
2091 smp_cores[idx as usize].apic_id = apic_id;
2092 smp_cores[idx as usize].acpi_id = acpi_id;
2093 smp_cores[idx as usize].is_bsp = is_bsp;
2094 smp_cores[idx as usize].is_active = is_bsp;
2095 smp_cores[idx as usize].stack_base = pmm_alloc_blocks(4) + (PAGE_SIZE * 4);
2096 smp_cores[idx as usize].current_task = 0;
2097 smp_core_count = smp_core_count + 1;
2098 if is_bsp { smp_bsp_id = apic_id; }
2099 }
2100
2101 fn smp_send_ipi(target_apic_id: u8, vector: u8, delivery_mode: u32, level: u32, trigger: u32) {
2102 let icr_low = (vector as u32) | (delivery_mode << 8) | (level << 14) | (trigger << 15);
2103 let icr_high = (target_apic_id as u32) << 24;
2104 lapic_write(LAPIC_ICRHI, icr_high);
2105 lapic_write(LAPIC_ICRLO, icr_low);
2106 while (lapic_read(LAPIC_ICRLO) & (1 << 12)) != 0 { cpu_pause(); }
2107 }
2108
2109 fn smp_send_init(target_apic_id: u8) {
2110 smp_send_ipi(target_apic_id, 0, 5, 1, 1);
2111 for i in 0..10000 { cpu_pause(); }
2112 smp_send_ipi(target_apic_id, 0, 5, 0, 1);
2113 }
2114
2115 fn smp_send_sipi(target_apic_id: u8, trampoline_page: u32) {
2116 let vector = (trampoline_page >> 12) as u8;
2117 smp_send_ipi(target_apic_id, vector, 6, 1, 0);
2118 }
2119
2120 fn smp_boot_ap(core_idx: u32) {
2121 let target_apic = smp_cores[core_idx as usize].apic_id;
2122 if target_apic == smp_bsp_id { return; }
2123 let trampoline = 0x8000;
2124 smp_send_init(target_apic);
2125 for i in 0..100000 { cpu_pause(); }
2126 smp_send_sipi(target_apic, trampoline);
2127 for i in 0..50000 { cpu_pause(); }
2128 smp_send_sipi(target_apic, trampoline);
2129 }
2130
2131 fn smp_init_all() {
2132 spin_init(&smp_lock);
2133 for i in 0..smp_core_count {
2134 smp_boot_ap(i);
2135 }
2136 }
2137
2138 struct HdaGcapRegs {
2139 gcap: u16,
2140 vmin: u8,
2141 vmaj: u8,
2142 outpay: u16,
2143 inpay: u16,
2144 gctl: u32,
2145 wakeen: u16,
2146 statests: u16,
2147 gsts: u16,
2148 outstrm: u16,
2149 instrm: u16,
2150 bidir: u16,
2151 }
2152
2153 struct HdaCorbRegs {
2154 corblbase: u32,
2155 corbubase: u32,
2156 corbwp: u16,
2157 corbrp: u16,
2158 corbctl: u8,
2159 corbsts: u8,
2160 corbsize: u8,
2161 rsvd: u8,
2162 }
2163
2164 struct HdaRirbRegs {
2165 rirblbase: u32,
2166 rirbubase: u32,
2167 rirbwp: u16,
2168 rintcnt: u16,
2169 rirbctl: u8,
2170 rirbsts: u8,
2171 rirbsize: u8,
2172 rsvd: u8,
2173 }
2174
2175 struct HdaStreamRegs {
2176 ctl0: u8,
2177 ctl1: u8,
2178 ctl2: u8,
2179 sts: u8,
2180 lpib: u32,
2181 cbl: u32,
2182 lvi: u16,
2183 fifos: u16,
2184 fmt: u16,
2185 rsvd: u16,
2186 bdpl: u32,
2187 bdpu: u32,
2188 }
2189
2190 let mut global_hda_base: u64 = 0;
2191 let mut hda_corb_buf: ptr<u32>;
2192 let mut hda_rirb_buf: ptr<u64>;
2193 let mut hda_corb_wp: u16 = 0;
2194 let mut hda_rirb_rp: u16 = 0;
2195 let mut hda_codec_mask: u16 = 0;
2196
2197 fn hda_reset_controller() {
2198 let gctl_ptr = (global_hda_base + 0x08) as ptr<u32>;
2199 *gctl_ptr = 0;
2200 while (*gctl_ptr & 1) != 0 { cpu_pause(); }
2201 *gctl_ptr = 1;
2202 while (*gctl_ptr & 1) == 0 { cpu_pause(); }
2203 for i in 0..50000 { cpu_pause(); }
2204 }
2205
2206 fn hda_init_corb_rirb() {
2207 let corb_regs = (global_hda_base + 0x40) as ptr<HdaCorbRegs>;
2208 let rirb_regs = (global_hda_base + 0x50) as ptr<HdaRirbRegs>;
2209 (*corb_regs).corbctl = 0;
2210 (*rirb_regs).rirbctl = 0;
2211
2212 hda_corb_buf = pmm_alloc_blocks(1) as ptr<u32>;
2213 hda_rirb_buf = pmm_alloc_blocks(1) as ptr<u64>;
2214 memset(hda_corb_buf as ptr<u8>, 0, PAGE_SIZE);
2215 memset(hda_rirb_buf as ptr<u8>, 0, PAGE_SIZE);
2216
2217 (*corb_regs).corblbase = hda_corb_buf as u64 as u32;
2218 (*corb_regs).corbubase = (hda_corb_buf as u64 >> 32) as u32;
2219 (*rirb_regs).rirblbase = hda_rirb_buf as u64 as u32;
2220 (*rirb_regs).rirbubase = (hda_rirb_buf as u64 >> 32) as u32;
2221
2222 (*corb_regs).corbrp = 0x8000;
2223 (*rirb_regs).rirbwp = 0x8000;
2224 (*corb_regs).corbwp = 0;
2225 hda_corb_wp = 0;
2226 hda_rirb_rp = 0;
2227
2228 (*corb_regs).corbctl = 2;
2229 (*rirb_regs).rirbctl = 2;
2230 }
2231
2232 fn hda_send_verb(codec: u8, node: u8, payload: u32) {
2233 let verb = ((codec as u32) << 28) | ((node as u32) << 20) | payload;
2234 let corb_regs = (global_hda_base + 0x40) as ptr<HdaCorbRegs>;
2235 hda_corb_wp = hda_corb_wp + 1;
2236 if hda_corb_wp == 256 { hda_corb_wp = 0; }
2237 *(hda_corb_buf + hda_corb_wp as u64) = verb;
2238 (*corb_regs).corbwp = hda_corb_wp;
2239 }
2240
2241 fn hda_read_response() -> u64 {
2242 let rirb_regs = (global_hda_base + 0x50) as ptr<HdaRirbRegs>;
2243 while (*rirb_regs).rirbwp == hda_rirb_rp { cpu_pause(); }
2244 hda_rirb_rp = hda_rirb_rp + 1;
2245 if hda_rirb_rp == 256 { hda_rirb_rp = 0; }
2246 return *(hda_rirb_buf + hda_rirb_rp as u64);
2247 }
2248
2249 fn hda_init(bar0: u64) {
2250 global_hda_base = bar0;
2251 hda_reset_controller();
2252 let statests_ptr = (global_hda_base + 0x0E) as ptr<u16>;
2253 hda_codec_mask = *statests_ptr;
2254 hda_init_corb_rirb();
2255 }
2256
2257 struct DhcpPacket {
2258 op: u8,
2259 htype: u8,
2260 hlen: u8,
2261 hops: u8,
2262 xid: u32,
2263 secs: u16,
2264 flags: u16,
2265 ciaddr: u32,
2266 yiaddr: u32,
2267 siaddr: u32,
2268 giaddr: u32,
2269 chaddr: [u8; 16],
2270 sname: [u8; 64],
2271 file: [u8; 128],
2272 magic: u32,
2273 options: [u8; 256],
2274 }
2275
2276 struct DnsHeader {
2277 id: u16,
2278 flags: u16,
2279 qdcount: u16,
2280 ancount: u16,
2281 nscount: u16,
2282 arcount: u16,
2283 }
2284
2285 let mut system_dns_ip: Ipv4Addr;
2286 let mut system_gateway_ip: Ipv4Addr;
2287 let mut system_subnet_mask: Ipv4Addr;
2288 let mut dhcp_xid: u32 = 0x1337AABB;
2289
2290 fn dhcp_send_discover() {
2291 let pkt_size = sizeof(DhcpPacket) as u64;
2292 let pkt = pmm_alloc_blocks(1) as ptr<DhcpPacket>;
2293 memset(pkt as ptr<u8>, 0, pkt_size);
2294 (*pkt).op = 1;
2295 (*pkt).htype = 1;
2296 (*pkt).hlen = 6;
2297 (*pkt).hops = 0;
2298 (*pkt).xid = htonl(dhcp_xid);
2299 (*pkt).secs = 0;
2300 (*pkt).flags = htons(0x8000);
2301 (*pkt).ciaddr = 0;
2302 (*pkt).yiaddr = 0;
2303 (*pkt).siaddr = 0;
2304 (*pkt).giaddr = 0;
2305 for i in 0..6 { (*pkt).chaddr[i] = system_mac.addr[i]; }
2306 (*pkt).magic = htonl(0x63825363);
2307 (*pkt).options[0] = 53;
2308 (*pkt).options[1] = 1;
2309 (*pkt).options[2] = 1;
2310 (*pkt).options[3] = 255;
2311
2312 let mut broadcast_ip: Ipv4Addr;
2313 for i in 0..4 { broadcast_ip.addr[i] = 255; }
2314
2315 let udp_len = sizeof(UdpHeader) as u64 + pkt_size;
2316 let ip_len = sizeof(Ipv4Header) as u64 + udp_len;
2317 let eth_len = sizeof(EthernetHeader) as u64 + ip_len;
2318 let buffer = pmm_alloc_blocks(1) as ptr<u8>;
2319 memset(buffer, 0, eth_len);
2320
2321 let eth = buffer as ptr<EthernetHeader>;
2322 for i in 0..6 { (*eth).dest_mac.addr[i] = 0xFF; }
2323 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
2324 (*eth).ethertype = htons(0x0800);
2325
2326 let iph = (buffer as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
2327 (*iph).ihl_version = 0x45;
2328 (*iph).tos = 0;
2329 (*iph).total_length = htons(ip_len as u16);
2330 (*iph).id = htons(1);
2331 (*iph).flags_frag = 0;
2332 (*iph).ttl = 64;
2333 (*iph).protocol = 17;
2334 (*iph).src_ip.addr[0] = 0; (*iph).src_ip.addr[1] = 0; (*iph).src_ip.addr[2] = 0; (*iph).src_ip.addr[3] = 0;
2335 for i in 0..4 { (*iph).dest_ip.addr[i] = 255; }
2336 (*iph).checksum = calculate_checksum(iph as ptr<u8>, sizeof(Ipv4Header) as u32);
2337
2338 let udph = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<UdpHeader>;
2339 (*udph).src_port = htons(68);
2340 (*udph).dest_port = htons(67);
2341 (*udph).length = htons(udp_len as u16);
2342 (*udph).checksum = 0;
2343
2344 let payload = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64 + sizeof(UdpHeader) as u64) as ptr<u8>;
2345 memcpy(payload, pkt as ptr<u8>, pkt_size);
2346
2347 rtl8139_send(buffer, eth_len as u32);
2348 pmm_free_blocks(pkt as u64, 1);
2349 pmm_free_blocks(buffer as u64, 1);
2350 }
2351
2352 fn dns_format_name(dest: ptr<u8>, domain: ptr<u8>) {
2353 let mut i: u64 = 0;
2354 let mut j: u64 = 0;
2355 let mut len_pos: u64 = 0;
2356 let mut count: u8 = 0;
2357 dest[len_pos] = 0;
2358 i = i + 1;
2359 while domain[j] != 0 {
2360 if domain[j] == 46 {
2361 dest[len_pos] = count;
2362 len_pos = i;
2363 count = 0;
2364 } else {
2365 dest[i] = domain[j];
2366 count = count + 1;
2367 }
2368 i = i + 1;
2369 j = j + 1;
2370 }
2371 dest[len_pos] = count;
2372 dest[i] = 0;
2373 }
2374
2375 fn dns_send_query(domain: ptr<u8>) {
2376 let mut query_buf: [u8; 256];
2377 memset(&query_buf[0] as ptr<u8>, 0, 256);
2378 let dh = &query_buf[0] as ptr<DnsHeader>;
2379 (*dh).id = htons(0xABCD);
2380 (*dh).flags = htons(0x0100);
2381 (*dh).qdcount = htons(1);
2382 (*dh).ancount = 0;
2383 (*dh).nscount = 0;
2384 (*dh).arcount = 0;
2385
2386 let qname = (&query_buf[0] as u64 + sizeof(DnsHeader) as u64) as ptr<u8>;
2387 dns_format_name(qname, domain);
2388 let qname_len = strlen(qname) + 1;
2389
2390 let qtype = (qname as u64 + qname_len) as ptr<u16>;
2391 *qtype = htons(1);
2392 let qclass = (qname as u64 + qname_len + 2) as ptr<u16>;
2393 *qclass = htons(1);
2394
2395 let total_len = sizeof(DnsHeader) as u64 + qname_len + 4;
2396
2397 let eth_len = sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64 + sizeof(UdpHeader) as u64 + total_len;
2398 let buffer = pmm_alloc_blocks(1) as ptr<u8>;
2399 memset(buffer, 0, eth_len);
2400
2401 let eth = buffer as ptr<EthernetHeader>;
2402 for i in 0..6 { (*eth).dest_mac.addr[i] = 0xFF; }
2403 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
2404 (*eth).ethertype = htons(0x0800);
2405
2406 let iph = (buffer as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
2407 (*iph).ihl_version = 0x45;
2408 (*iph).tos = 0;
2409 (*iph).total_length = htons((sizeof(Ipv4Header) as u64 + sizeof(UdpHeader) as u64 + total_len) as u16);
2410 (*iph).id = htons(2);
2411 (*iph).flags_frag = 0;
2412 (*iph).ttl = 64;
2413 (*iph).protocol = 17;
2414 for i in 0..4 { (*iph).src_ip.addr[i] = system_ip.addr[i]; }
2415 for i in 0..4 { (*iph).dest_ip.addr[i] = system_dns_ip.addr[i]; }
2416 (*iph).checksum = calculate_checksum(iph as ptr<u8>, sizeof(Ipv4Header) as u32);
2417
2418 let udph = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<UdpHeader>;
2419 (*udph).src_port = htons(50000);
2420 (*udph).dest_port = htons(53);
2421 (*udph).length = htons((sizeof(UdpHeader) as u64 + total_len) as u16);
2422 (*udph).checksum = 0;
2423
2424 let payload = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64 + sizeof(UdpHeader) as u64) as ptr<u8>;
2425 memcpy(payload, &query_buf[0] as ptr<u8>, total_len);
2426
2427 rtl8139_send(buffer, eth_len as u32);
2428 pmm_free_blocks(buffer as u64, 1);
2429 }
2430
2431 struct UsbCbw {
2432 signature: u32,
2433 tag: u32,
2434 transfer_length: u32,
2435 flags: u8,
2436 lun: u8,
2437 cb_length: u8,
2438 cdb: [u8; 16],
2439 }
2440
2441 struct UsbCsw {
2442 signature: u32,
2443 tag: u32,
2444 data_residue: u32,
2445 status: u8,
2446 }
2447
2448 fn usb_bot_read_capacity(bulk_out: u8, bulk_in: u8) {
2449 let cbw = pmm_alloc_blocks(1) as ptr<UsbCbw>;
2450 memset(cbw as ptr<u8>, 0, sizeof(UsbCbw) as u64);
2451 (*cbw).signature = 0x43425355;
2452 (*cbw).tag = 0x11223344;
2453 (*cbw).transfer_length = 8;
2454 (*cbw).flags = 0x80;
2455 (*cbw).lun = 0;
2456 (*cbw).cb_length = 10;
2457 (*cbw).cdb[0] = 0x25;
2458 pmm_free_blocks(cbw as u64, 1);
2459 }
2460
2461 struct Psf1Header {
2462 magic: u16,
2463 mode: u8,
2464 charsize: u8,
2465 }
2466
2467 struct Psf2Header {
2468 magic: u32,
2469 version: u32,
2470 headersize: u32,
2471 flags: u32,
2472 length: u32,
2473 charsize: u32,
2474 height: u32,
2475 width: u32,
2476 }
2477
2478 let mut system_font_ptr: ptr<u8>;
2479 let mut system_font_w: u32 = 8;
2480 let mut system_font_h: u32 = 16;
2481
2482 fn gui_draw_char(win: ptr<CompositorWindow>, c: u8, x: u32, y: u32, fg: u32, bg: u32) {
2483 let glyph_offset = c as u64 * system_font_h as u64;
2484 let glyph = (system_font_ptr as u64 + glyph_offset) as ptr<u8>;
2485 let buf = (*win).buffer_phys as ptr<u32>;
2486 for cy in 0..system_font_h {
2487 let row = *(glyph + cy as u64);
2488 for cx in 0..system_font_w {
2489 let px = x + cx;
2490 let py = y + cy;
2491 if px < (*win).width && py < (*win).height {
2492 let p_idx = (py * (*win).width + px) as u64;
2493 if (row & (0x80 >> cx)) != 0 {
2494 *(buf + p_idx) = fg;
2495 } else {
2496 if bg != 0xFFFFFFFF { *(buf + p_idx) = bg; }
2497 }
2498 }
2499 }
2500 }
2501 }
2502
2503 fn gui_draw_string(win: ptr<CompositorWindow>, str: ptr<u8>, x: u32, y: u32, fg: u32, bg: u32) {
2504 let mut i: u64 = 0;
2505 let mut cx = x;
2506 while *(str + i) != 0 {
2507 if *(str + i) == 10 {
2508 cx = x;
2509 y = y + system_font_h + 2;
2510 } else {
2511 gui_draw_char(win, *(str + i), cx, y, fg, bg);
2512 cx = cx + system_font_w;
2513 }
2514 i = i + 1;
2515 }
2516 }
2517
2518 fn gui_draw_button(win: ptr<CompositorWindow>, label: ptr<u8>, x: u32, y: u32, w: u32, h: u32) {
2519 comp_draw_rect(win, x, y, w, h, 0x555555);
2520 comp_draw_rect(win, x+1, y+1, w-2, h-2, 0x888888);
2521 let len = strlen(label) as u32;
2522 let text_x = x + (w / 2) - ((len * system_font_w) / 2);
2523 let text_y = y + (h / 2) - (system_font_h / 2);
2524 gui_draw_string(win, label, text_x, text_y, 0xFFFFFF, 0xFFFFFFFF);
2525 }
2526
2527 fn gui_draw_panel(win: ptr<CompositorWindow>, title: ptr<u8>) {
2528 comp_draw_rect(win, 0, 0, (*win).width, (*win).height, 0x333333);
2529 comp_draw_rect(win, 0, 0, (*win).width, 24, 0x111111);
2530 gui_draw_string(win, title, 5, 4, 0xFFFFFF, 0x111111);
2531 gui_draw_button(win, "X" as ptr<u8>, (*win).width - 24, 2, 20, 20);
2532 }
2533
2534 const TCP_STATE_CLOSED: u8 = 0;
2535 const TCP_STATE_LISTEN: u8 = 1;
2536 const TCP_STATE_SYN_SENT: u8 = 2;
2537 const TCP_STATE_SYN_RCVD: u8 = 3;
2538 const TCP_STATE_ESTABLISHED: u8 = 4;
2539 const TCP_STATE_FIN_WAIT_1: u8 = 5;
2540 const TCP_STATE_FIN_WAIT_2: u8 = 6;
2541 const TCP_STATE_CLOSE_WAIT: u8 = 7;
2542 const TCP_STATE_CLOSING: u8 = 8;
2543 const TCP_STATE_LAST_ACK: u8 = 9;
2544 const TCP_STATE_TIME_WAIT: u8 = 10;
2545
2546 struct TcpSocket {
2547 id: u64,
2548 state: u8,
2549 local_port: u16,
2550 remote_port: u16,
2551 remote_ip: Ipv4Addr,
2552 seq_num: u32,
2553 ack_num: u32,
2554 window_size: u16,
2555 rx_buffer: ptr<u8>,
2556 tx_buffer: ptr<u8>,
2557 rx_head: u32,
2558 rx_tail: u32,
2559 tx_head: u32,
2560 tx_tail: u32,
2561 lock: Spinlock,
2562 is_active: bool,
2563 }
2564
2565 let mut global_tcp_sockets: [TcpSocket; 1024];
2566 let mut tcp_socket_count: u64 = 1;
2567
2568 fn tcp_init_sockets() {
2569 for i in 0..1024 {
2570 global_tcp_sockets[i].is_active = false;
2571 global_tcp_sockets[i].id = 0;
2572 spin_init(&(global_tcp_sockets[i].lock));
2573 }
2574 }
2575
2576 fn tcp_create_socket() -> ptr<TcpSocket> {
2577 for i in 0..1024 {
2578 if !global_tcp_sockets[i].is_active {
2579 global_tcp_sockets[i].is_active = true;
2580 global_tcp_sockets[i].id = tcp_socket_count;
2581 tcp_socket_count = tcp_socket_count + 1;
2582 global_tcp_sockets[i].state = TCP_STATE_CLOSED;
2583 global_tcp_sockets[i].local_port = 0;
2584 global_tcp_sockets[i].remote_port = 0;
2585 global_tcp_sockets[i].seq_num = 0;
2586 global_tcp_sockets[i].ack_num = 0;
2587 global_tcp_sockets[i].window_size = 8192;
2588 global_tcp_sockets[i].rx_buffer = pmm_alloc_blocks(2) as ptr<u8>;
2589 global_tcp_sockets[i].tx_buffer = pmm_alloc_blocks(2) as ptr<u8>;
2590 global_tcp_sockets[i].rx_head = 0;
2591 global_tcp_sockets[i].rx_tail = 0;
2592 global_tcp_sockets[i].tx_head = 0;
2593 global_tcp_sockets[i].tx_tail = 0;
2594 return &global_tcp_sockets[i];
2595 }
2596 }
2597 return 0 as ptr<TcpSocket>;
2598 }
2599
2600 fn tcp_compute_checksum(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, tcp_len: u16, tcp_data: ptr<u8>) -> u16 {
2601 let mut sum: u32 = 0;
2602 let src_ptr = &src_ip as ptr<Ipv4Addr> as ptr<u16>;
2603 let dst_ptr = &dst_ip as ptr<Ipv4Addr> as ptr<u16>;
2604 sum = sum + *(src_ptr) as u32;
2605 sum = sum + *(src_ptr as u64 + 2) as u32;
2606 sum = sum + *(dst_ptr) as u32;
2607 sum = sum + *(dst_ptr as u64 + 2) as u32;
2608 sum = sum + htons(6) as u32;
2609 sum = sum + htons(tcp_len) as u32;
2610
2611 let mut data_ptr = tcp_data as ptr<u16>;
2612 let mut len = tcp_len;
2613 while len > 1 {
2614 sum = sum + *(data_ptr) as u32;
2615 data_ptr = (data_ptr as u64 + 2) as ptr<u16>;
2616 len = len - 2;
2617 }
2618 if len == 1 {
2619 let mut last_byte: u16 = 0;
2620 *(last_byte as u64 as ptr<u8>) = *(data_ptr as ptr<u8>);
2621 sum = sum + last_byte as u32;
2622 }
2623 while (sum >> 16) != 0 {
2624 sum = (sum & 0xFFFF) + (sum >> 16);
2625 }
2626 return (!sum) as u16;
2627 }
2628
2629 fn tcp_send_segment(sock: ptr<TcpSocket>, flags: u16, payload: ptr<u8>, payload_len: u16) {
2630 let tcp_len = sizeof(TcpHeader) as u16 + payload_len;
2631 let ip_len = sizeof(Ipv4Header) as u16 + tcp_len;
2632 let eth_len = sizeof(EthernetHeader) as u16 + ip_len;
2633
2634 let buffer = pmm_alloc_blocks(1) as ptr<u8>;
2635 memset(buffer, 0, eth_len as u64);
2636
2637 let eth = buffer as ptr<EthernetHeader>;
2638 for i in 0..6 { (*eth).dest_mac.addr[i] = 0xFF; }
2639 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
2640 (*eth).ethertype = htons(0x0800);
2641
2642 let iph = (buffer as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
2643 (*iph).ihl_version = 0x45;
2644 (*iph).tos = 0;
2645 (*iph).total_length = htons(ip_len);
2646 (*iph).id = htons(tcp_socket_count as u16);
2647 (*iph).flags_frag = 0;
2648 (*iph).ttl = 64;
2649 (*iph).protocol = 6;
2650 for i in 0..4 { (*iph).src_ip.addr[i] = system_ip.addr[i]; }
2651 for i in 0..4 { (*iph).dest_ip.addr[i] = (*sock).remote_ip.addr[i]; }
2652 (*iph).checksum = calculate_checksum(iph as ptr<u8>, sizeof(Ipv4Header) as u32);
2653
2654 let tcph = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
2655 (*tcph).src_port = htons((*sock).local_port);
2656 (*tcph).dest_port = htons((*sock).remote_port);
2657 (*tcph).seq_num = htonl((*sock).seq_num);
2658 (*tcph).ack_num = htonl((*sock).ack_num);
2659 (*tcph).data_offset_flags = htons((5 << 12) | flags);
2660 (*tcph).window_size = htons((*sock).window_size);
2661 (*tcph).urgent_ptr = 0;
2662
2663 let tcp_payload = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64 + sizeof(TcpHeader) as u64) as ptr<u8>;
2664 if payload_len > 0 {
2665 memcpy(tcp_payload, payload, payload_len as u64);
2666 }
2667
2668 (*tcph).checksum = tcp_compute_checksum(system_ip, (*sock).remote_ip, tcp_len, tcph as ptr<u8>);
2669 rtl8139_send(buffer, eth_len as u32);
2670 pmm_free_blocks(buffer as u64, 1);
2671 }
2672
2673 fn tcp_connect(sock: ptr<TcpSocket>, remote_ip: Ipv4Addr, remote_port: u16) {
2674 spin_lock(&((*sock).lock));
2675 (*sock).remote_ip = remote_ip;
2676 (*sock).remote_port = remote_port;
2677 if (*sock).local_port == 0 {
2678 (*sock).local_port = 49152 + (tcp_socket_count as u16 % 16384);
2679 }
2680 (*sock).seq_num = 0x11223344;
2681 (*sock).state = TCP_STATE_SYN_SENT;
2682 tcp_send_segment(sock, 0x0002, 0 as ptr<u8>, 0);
2683 spin_unlock(&((*sock).lock));
2684 }
2685
2686 fn tcp_close(sock: ptr<TcpSocket>) {
2687 spin_lock(&((*sock).lock));
2688 if (*sock).state == TCP_STATE_ESTABLISHED || (*sock).state == TCP_STATE_SYN_RCVD {
2689 (*sock).state = TCP_STATE_FIN_WAIT_1;
2690 tcp_send_segment(sock, 0x0011, 0 as ptr<u8>, 0);
2691 } else {
2692 (*sock).state = TCP_STATE_CLOSED;
2693 (*sock).is_active = false;
2694 pmm_free_blocks((*sock).rx_buffer as u64, 2);
2695 pmm_free_blocks((*sock).tx_buffer as u64, 2);
2696 }
2697 spin_unlock(&((*sock).lock));
2698 }
2699
2700 fn tcp_bind(sock: ptr<TcpSocket>, port: u16) {
2701 spin_lock(&((*sock).lock));
2702 (*sock).local_port = port;
2703 spin_unlock(&((*sock).lock));
2704 }
2705
2706 fn tcp_listen(sock: ptr<TcpSocket>) {
2707 spin_lock(&((*sock).lock));
2708 (*sock).state = TCP_STATE_LISTEN;
2709 spin_unlock(&((*sock).lock));
2710 }
2711
2712 struct Fat32ExtBPB {
2713 jmp: [u8; 3],
2714 oem_name: [u8; 8],
2715 bytes_per_sector: u16,
2716 sectors_per_cluster: u8,
2717 reserved_sector_count: u16,
2718 num_fats: u8,
2719 root_entry_count: u16,
2720 total_sectors_16: u16,
2721 media_type: u8,
2722 table_size_16: u16,
2723 sectors_per_track: u16,
2724 head_side_count: u16,
2725 hidden_sector_count: u32,
2726 total_sectors_32: u32,
2727 table_size_32: u32,
2728 extended_flags: u16,
2729 fat_version: u16,
2730 root_cluster: u32,
2731 fat_info: u16,
2732 backup_boot_sector: u16,
2733 reserved_0: [u8; 12],
2734 drive_number: u8,
2735 reserved_1: u8,
2736 boot_signature: u8,
2737 volume_id: u32,
2738 volume_label: [u8; 11],
2739 fat_type_label: [u8; 8],
2740 }
2741
2742 struct Fat32DirEntry {
2743 name: [u8; 11],
2744 attr: u8,
2745 nt_res: u8,
2746 crt_time_tenth: u8,
2747 crt_time: u16,
2748 crt_date: u16,
2749 lst_acc_date: u16,
2750 fst_clus_hi: u16,
2751 wrt_time: u16,
2752 wrt_date: u16,
2753 fst_clus_lo: u16,
2754 file_size: u32,
2755 }
2756
2757 let mut fat32_lba_start: u32 = 0;
2758 let mut fat32_fat_start: u32 = 0;
2759 let mut fat32_data_start: u32 = 0;
2760 let mut fat32_root_cluster: u32 = 0;
2761 let mut fat32_sectors_per_cluster: u32 = 0;
2762 let mut fat32_bytes_per_sector: u32 = 0;
2763
2764 fn fat32_init(lba_offset: u32) {
2765 fat32_lba_start = lba_offset;
2766 let bpb_buf = pmm_alloc_blocks(1) as ptr<u8>;
2767 let bpb = bpb_buf as ptr<Fat32ExtBPB>;
2768 fat32_bytes_per_sector = (*bpb).bytes_per_sector as u32;
2769 fat32_sectors_per_cluster = (*bpb).sectors_per_cluster as u32;
2770 fat32_fat_start = fat32_lba_start + (*bpb).reserved_sector_count as u32;
2771 let fat_size = (*bpb).table_size_32;
2772 fat32_data_start = fat32_fat_start + ((*bpb).num_fats as u32 * fat_size);
2773 fat32_root_cluster = (*bpb).root_cluster;
2774 pmm_free_blocks(bpb_buf as u64, 1);
2775 }
2776
2777 fn fat32_cluster_to_lba(cluster: u32) -> u32 {
2778 return fat32_data_start + ((cluster - 2) * fat32_sectors_per_cluster);
2779 }
2780
2781 fn fat32_read_next_cluster(cluster: u32) -> u32 {
2782 let fat_offset = cluster * 4;
2783 let fat_sector = fat32_fat_start + (fat_offset / fat32_bytes_per_sector);
2784 let ent_offset = fat_offset % fat32_bytes_per_sector;
2785 let buf = pmm_alloc_blocks(1) as ptr<u8>;
2786 let next_cluster = *((buf as u64 + ent_offset as u64) as ptr<u32>) & 0x0FFFFFFF;
2787 pmm_free_blocks(buf as u64, 1);
2788 return next_cluster;
2789 }
2790
2791 fn fat32_find_file(dir_cluster: u32, filename: ptr<u8>) -> ptr<Fat32DirEntry> {
2792 let mut current_cluster = dir_cluster;
2793 let buf = pmm_alloc_blocks(1) as ptr<u8>;
2794 while current_cluster < 0x0FFFFFF8 {
2795 let entries_per_cluster = (fat32_sectors_per_cluster * fat32_bytes_per_sector) / 32;
2796 for i in 0..entries_per_cluster {
2797 let entry = (buf as u64 + (i * 32) as u64) as ptr<Fat32DirEntry>;
2798 if (*entry).name[0] == 0x00 {
2799 pmm_free_blocks(buf as u64, 1);
2800 return 0 as ptr<Fat32DirEntry>;
2801 }
2802 if (*entry).name[0] != 0xE5 && ((*entry).attr & 0x0F) != 0x0F {
2803 let mut match_found = true;
2804 for j in 0..11 {
2805 if (*entry).name[j as usize] != *(filename + j) {
2806 match_found = false;
2807 break;
2808 }
2809 }
2810 if match_found {
2811 let ret_entry = pmm_alloc_blocks(1) as ptr<Fat32DirEntry>;
2812 memcpy(ret_entry as ptr<u8>, entry as ptr<u8>, 32);
2813 pmm_free_blocks(buf as u64, 1);
2814 return ret_entry;
2815 }
2816 }
2817 }
2818 current_cluster = fat32_read_next_cluster(current_cluster);
2819 }
2820 pmm_free_blocks(buf as u64, 1);
2821 return 0 as ptr<Fat32DirEntry>;
2822 }
2823
2824 fn acpi_get_pm1_control() -> (u32, u32) {
2825 if acpi_fadt == 0 as ptr<FADTHeader> { return (0, 0); }
2826 let pm1a = (*acpi_fadt).pm1a_control_block;
2827 let pm1b = (*acpi_fadt).pm1b_control_block;
2828 return (pm1a, pm1b);
2829 }
2830
2831 fn acpi_power_off() {
2832 let (pm1a, pm1b) = acpi_get_pm1_control();
2833 if pm1a != 0 {
2834 let val = inw(pm1a as u16);
2835 outw(pm1a as u16, val | (5 << 10) | (1 << 13));
2836 }
2837 if pm1b != 0 {
2838 let val = inw(pm1b as u16);
2839 outw(pm1b as u16, val | (5 << 10) | (1 << 13));
2840 }
2841 cpu_cli();
2842 loop { cpu_hlt(); }
2843 }
2844
2845 fn acpi_reset() {
2846 let reset_reg = 0x64;
2847 let reset_cmd = 0xFE;
2848 while (inb(reset_reg) & 2) != 0 { cpu_pause(); }
2849 outb(reset_reg, reset_cmd);
2850 cpu_cli();
2851 loop { cpu_hlt(); }
2852 }
2853
2854 fn gui_draw_checkbox(win: ptr<CompositorWindow>, x: u32, y: u32, checked: bool, label: ptr<u8>) {
2855 comp_draw_rect(win, x, y, 16, 16, 0xFFFFFF);
2856 comp_draw_rect(win, x+1, y+1, 14, 14, 0x222222);
2857 if checked {
2858 comp_draw_rect(win, x+4, y+4, 8, 8, 0x00FF00);
2859 }
2860 gui_draw_string(win, label, x + 24, y, 0xFFFFFF, 0xFFFFFFFF);
2861 }
2862
2863 fn gui_draw_radio(win: ptr<CompositorWindow>, x: u32, y: u32, selected: bool, label: ptr<u8>) {
2864 comp_draw_rect(win, x, y, 16, 16, 0x888888);
2865 comp_draw_rect(win, x+2, y+2, 12, 12, 0x222222);
2866 if selected {
2867 comp_draw_rect(win, x+5, y+5, 6, 6, 0x00AFFF);
2868 }
2869 gui_draw_string(win, label, x + 24, y, 0xFFFFFF, 0xFFFFFFFF);
2870 }
2871
2872 fn gui_draw_progressbar(win: ptr<CompositorWindow>, x: u32, y: u32, w: u32, h: u32, progress: u32, max: u32) {
2873 comp_draw_rect(win, x, y, w, h, 0x444444);
2874 comp_draw_rect(win, x+1, y+1, w-2, h-2, 0x111111);
2875 let mut fill_w = 0;
2876 if max > 0 {
2877 fill_w = (progress * (w - 2)) / max;
2878 }
2879 if fill_w > 0 {
2880 comp_draw_rect(win, x+1, y+1, fill_w, h-2, 0x00FF00);
2881 }
2882 }
2883
2884 fn gui_draw_slider(win: ptr<CompositorWindow>, x: u32, y: u32, w: u32, val: u32, max: u32) {
2885 let h = 10;
2886 comp_draw_rect(win, x, y + 4, w, 2, 0x888888);
2887 let mut pos_x = 0;
2888 if max > 0 {
2889 pos_x = (val * w) / max;
2890 }
2891 if pos_x > w - 8 { pos_x = w - 8; }
2892 comp_draw_rect(win, x + pos_x, y, 8, h, 0xFFFFFF);
2893 }
2894
2895 struct AudioMixerChannel {
2896 is_playing: bool,
2897 buffer: ptr<u8>,
2898 length: u32,
2899 position: u32,
2900 volume: u8,
2901 sample_rate: u32,
2902 }
2903
2904 let mut global_audio_mixer: [AudioMixerChannel; 16];
2905
2906 fn mixer_init() {
2907 for i in 0..16 {
2908 global_audio_mixer[i].is_playing = false;
2909 global_audio_mixer[i].position = 0;
2910 global_audio_mixer[i].volume = 128;
2911 }
2912 }
2913
2914 fn mixer_play_pcm(buffer: ptr<u8>, length: u32, rate: u32) -> i32 {
2915 for i in 0..16 {
2916 if !global_audio_mixer[i].is_playing {
2917 global_audio_mixer[i].buffer = buffer;
2918 global_audio_mixer[i].length = length;
2919 global_audio_mixer[i].position = 0;
2920 global_audio_mixer[i].sample_rate = rate;
2921 global_audio_mixer[i].is_playing = true;
2922 return i as i32;
2923 }
2924 }
2925 return -1;
2926 }
2927
2928 fn mixer_stop_channel(channel: u32) {
2929 if channel < 16 {
2930 global_audio_mixer[channel as usize].is_playing = false;
2931 }
2932 }
2933
2934 fn mixer_process_frame(output_buffer: ptr<u16>, frames: u32) {
2935 for f in 0..frames {
2936 let mut mixed_sample_l: i32 = 0;
2937 let mut mixed_sample_r: i32 = 0;
2938 for c in 0..16 {
2939 let mut ch = &global_audio_mixer[c];
2940 if (*ch).is_playing && (*ch).position < (*ch).length {
2941 let sample_ptr = ((*ch).buffer as u64 + (*ch).position as u64 * 4) as ptr<i16>;
2942 let left = (*sample_ptr as i32 * (*ch).volume as i32) / 255;
2943 let right = (*(sample_ptr as u64 + 2) as ptr<i16> as i32 * (*ch).volume as i32) / 255;
2944 mixed_sample_l = mixed_sample_l + left;
2945 mixed_sample_r = mixed_sample_r + right;
2946 (*ch).position = (*ch).position + 1;
2947 } else if (*ch).is_playing {
2948 (*ch).is_playing = false;
2949 }
2950 }
2951 if mixed_sample_l > 32767 { mixed_sample_l = 32767; }
2952 if mixed_sample_l < -32768 { mixed_sample_l = -32768; }
2953 if mixed_sample_r > 32767 { mixed_sample_r = 32767; }
2954 if mixed_sample_r < -32768 { mixed_sample_r = -32768; }
2955
2956 *(output_buffer as u64 + f as u64 * 4) as ptr<i16> = mixed_sample_l as i16;
2957 *(output_buffer as u64 + f as u64 * 4 + 2) as ptr<i16> = mixed_sample_r as i16;
2958 }
2959 }
2960
2961 let mut usb_hid_kbd_map: [u8; 128] = [
2962 0, 0, 0, 0, 'a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8, 'f' as u8, 'g' as u8, 'h' as u8, 'i' as u8, 'j' as u8, 'k' as u8, 'l' as u8,
2963 'm' as u8, 'n' as u8, 'o' as u8, 'p' as u8, 'q' as u8, 'r' as u8, 's' as u8, 't' as u8, 'u' as u8, 'v' as u8, 'w' as u8, 'x' as u8, 'y' as u8, 'z' as u8,
2964 '1' as u8, '2' as u8, '3' as u8, '4' as u8, '5' as u8, '6' as u8, '7' as u8, '8' as u8, '9' as u8, '0' as u8,
2965 10, 27, 8, 9, ' ' as u8, '-' as u8, '=' as u8, '[' as u8, ']' as u8, '\\' as u8, 0, ';' as u8, '\'' as u8, '`' as u8, ',' as u8, '.' as u8, '/' as u8,
2966 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2967 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2968 ];
2969
2970 let mut usb_hid_shift_map: [u8; 128] = [
2971 0, 0, 0, 0, 'A' as u8, 'B' as u8, 'C' as u8, 'D' as u8, 'E' as u8, 'F' as u8, 'G' as u8, 'H' as u8, 'I' as u8, 'J' as u8, 'K' as u8, 'L' as u8,
2972 'M' as u8, 'N' as u8, 'O' as u8, 'P' as u8, 'Q' as u8, 'R' as u8, 'S' as u8, 'T' as u8, 'U' as u8, 'V' as u8, 'W' as u8, 'X' as u8, 'Y' as u8, 'Z' as u8,
2973 '!' as u8, '@' as u8, '#' as u8, '$' as u8, '%' as u8, '^' as u8, '&' as u8, '*' as u8, '(' as u8, ')' as u8,
2974 10, 27, 8, 9, ' ' as u8, '_' as u8, '+' as u8, '{' as u8, '}' as u8, '|' as u8, 0, ':' as u8, '"' as u8, '~' as u8, '<' as u8, '>' as u8, '?' as u8,
2975 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2976 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2977 ];
2978
2979 struct UsbDeviceDescriptor {
2980 length: u8,
2981 descriptor_type: u8,
2982 bcd_usb: u16,
2983 device_class: u8,
2984 device_subclass: u8,
2985 device_protocol: u8,
2986 max_packet_size: u8,
2987 id_vendor: u16,
2988 id_product: u16,
2989 bcd_device: u16,
2990 manufacturer: u8,
2991 product: u8,
2992 serial_number: u8,
2993 num_configurations: u8,
2994 }
2995
2996 struct UsbEndpointDescriptor {
2997 length: u8,
2998 descriptor_type: u8,
2999 endpoint_address: u8,
3000 attributes: u8,
3001 max_packet_size: u16,
3002 interval: u8,
3003 }
3004
3005 struct HidReport {
3006 modifier: u8,
3007 reserved: u8,
3008 keys: [u8; 6],
3009 }
3010
3011 struct MouseReport {
3012 buttons: u8,
3013 x: i8,
3014 y: i8,
3015 wheel: i8,
3016 }
3017
3018 let mut global_kbd_state_shift: bool = false;
3019 let mut global_kbd_state_caps: bool = false;
3020
3021 fn usb_hid_parse_keyboard(report: ptr<HidReport>) {
3022 let m = (*report).modifier;
3023 global_kbd_state_shift = (m & 0x02) != 0 || (m & 0x20) != 0;
3024
3025 for i in 0..6 {
3026 let k = (*report).keys[i];
3027 if k >= 4 && k <= 100 {
3028 let mut ascii = usb_hid_kbd_map[k as usize];
3029 if global_kbd_state_shift != global_kbd_state_caps {
3030 if k >= 4 && k <= 29 { ascii = usb_hid_shift_map[k as usize]; }
3031 }
3032 if global_kbd_state_shift && (k < 4 || k > 29) {
3033 ascii = usb_hid_shift_map[k as usize];
3034 }
3035 if ascii != 0 {
3036 kbd_buf[kbd_wp as usize] = ascii;
3037 kbd_wp = (kbd_wp + 1) % 1024;
3038 }
3039 }
3040 }
3041 }
3042
3043 fn usb_hid_parse_mouse(report: ptr<MouseReport>) {
3044 let btn = (*report).buttons;
3045 let dx = (*report).x as i32;
3046 let dy = (*report).y as i32;
3047
3048 mouse_x = mouse_x + dx;
3049 mouse_y = mouse_y + dy;
3050
3051 if mouse_x < 0 { mouse_x = 0; }
3052 if mouse_y < 0 { mouse_y = 0; }
3053 if mouse_x >= comp_width as i32 { mouse_x = comp_width as i32 - 1; }
3054 if mouse_y >= comp_height as i32 { mouse_y = comp_height as i32 - 1; }
3055
3056 mouse_b = btn;
3057 }
3058
3059 const SWAP_MAGIC: u64 = 0x5357415053504143;
3060 const MAX_SWAP_PAGES: u64 = 262144;
3061
3062 struct SwapHeader {
3063 magic: u64,
3064 total_pages: u64,
3065 free_pages: u64,
3066 bitmap_offset: u64,
3067 }
3068
3069 struct PageFrameInfo {
3070 phys_addr: u64,
3071 virt_addr: u64,
3072 pid: u64,
3073 access_time: u64,
3074 flags: u32,
3075 swap_idx: u64,
3076 }
3077
3078 let mut swap_bitmap: ptr<u64>;
3079 let mut pfn_database: ptr<PageFrameInfo>;
3080 let mut pfn_count: u64 = 0;
3081 let mut current_time_tick: u64 = 0;
3082 let mut swap_lck: Spinlock;
3083
3084 fn swap_init() {
3085 spin_init(&swap_lck);
3086 let bitmap_sz = MAX_SWAP_PAGES / 64 * 8;
3087 swap_bitmap = pmm_alloc_blocks(bitmap_sz / PAGE_SIZE + 1) as ptr<u64>;
3088 memset(swap_bitmap as ptr<u8>, 0, bitmap_sz);
3089
3090 let pfn_sz = (MAX_MEM_MB * 1024 * 1024) / PAGE_SIZE * sizeof(PageFrameInfo) as u64;
3091 pfn_database = pmm_alloc_blocks(pfn_sz / PAGE_SIZE + 1) as ptr<PageFrameInfo>;
3092 memset(pfn_database as ptr<u8>, 0, pfn_sz);
3093 }
3094
3095 fn swap_alloc_slot() -> u64 {
3096 for i in 0..(MAX_SWAP_PAGES / 64) {
3097 if *(swap_bitmap + i) != 0xFFFFFFFFFFFFFFFF {
3098 for j in 0..64 {
3099 if (*(swap_bitmap + i) & (1 << j)) == 0 {
3100 *(swap_bitmap + i) |= 1 << j;
3101 return i * 64 + j;
3102 }
3103 }
3104 }
3105 }
3106 return 0xFFFFFFFFFFFFFFFF;
3107 }
3108
3109 fn swap_free_slot(idx: u64) {
3110 *(swap_bitmap + (idx / 64)) &= !(1 << (idx % 64));
3111 }
3112
3113 fn page_replacement_lru() -> ptr<PageFrameInfo> {
3114 let mut oldest_time: u64 = 0xFFFFFFFFFFFFFFFF;
3115 let mut victim: ptr<PageFrameInfo> = 0 as ptr<PageFrameInfo>;
3116
3117 for i in 0..pfn_count {
3118 let frame = (pfn_database as u64 + i * sizeof(PageFrameInfo) as u64) as ptr<PageFrameInfo>;
3119 if ((*frame).flags & 1) != 0 && ((*frame).flags & 2) == 0 {
3120 if (*frame).access_time < oldest_time {
3121 oldest_time = (*frame).access_time;
3122 victim = frame;
3123 }
3124 }
3125 }
3126 return victim;
3127 }
3128
3129 fn swap_page_out(frame: ptr<PageFrameInfo>) -> bool {
3130 spin_lock(&swap_lck);
3131 let slot = swap_alloc_slot();
3132 if slot == 0xFFFFFFFFFFFFFFFF {
3133 spin_unlock(&swap_lck);
3134 return false;
3135 }
3136
3137 let disk_lba = 1000000 + (slot * 8);
3138 (*frame).swap_idx = slot;
3139 (*frame).flags &= !1;
3140 vmm_unmap_page((*frame).virt_addr);
3141
3142 spin_unlock(&swap_lck);
3143 return true;
3144 }
3145
3146 fn swap_page_in(frame: ptr<PageFrameInfo>) {
3147 spin_lock(&swap_lck);
3148 let phys = pmm_alloc_blocks(1);
3149 if phys == 0 {
3150 let victim = page_replacement_lru();
3151 if victim != 0 as ptr<PageFrameInfo> {
3152 swap_page_out(victim);
3153 }
3154 }
3155
3156 let disk_lba = 1000000 + ((*frame).swap_idx * 8);
3157 (*frame).phys_addr = phys;
3158 (*frame).flags |= 1;
3159 vmm_map_page(phys, (*frame).virt_addr, 0x07);
3160 swap_free_slot((*frame).swap_idx);
3161 spin_unlock(&swap_lck);
3162 }
3163
3164 fn page_fault_handler_adv(cr2: u64, err_code: u64) {
3165 let virt_align = cr2 & !(PAGE_SIZE - 1);
3166 for i in 0..pfn_count {
3167 let frame = (pfn_database as u64 + i * sizeof(PageFrameInfo) as u64) as ptr<PageFrameInfo>;
3168 if (*frame).virt_addr == virt_align && ((*frame).flags & 1) == 0 {
3169 swap_page_in(frame);
3170 return;
3171 }
3172 }
3173 cpu_cli();
3174 loop { cpu_hlt(); }
3175 }
3176
3177 struct Vec3 { x: f32, y: f32, z: f32, w: f32 }
3178 struct Mat4 { m: [[f32; 4]; 4] }
3179
3180 fn math_abs(a: f32) -> f32 { if a < 0.0 { return -a; } return a; }
3181 fn math_fmod(a: f32, b: f32) -> f32 {
3182 let mut res = a;
3183 while res >= b { res = res - b; }
3184 while res < 0.0 { res = res + b; }
3185 return res;
3186 }
3187
3188 fn taylor_sin(mut x: f32) -> f32 {
3189 let PI2 = 6.28318530718;
3190 x = math_fmod(x, PI2);
3191 if x > 3.14159265 { x = x - PI2; }
3192 let x2 = x * x;
3193 let x3 = x2 * x;
3194 let x5 = x3 * x2;
3195 let x7 = x5 * x2;
3196 return x - (x3 / 6.0) + (x5 / 120.0) - (x7 / 5040.0);
3197 }
3198
3199 fn taylor_cos(mut x: f32) -> f32 {
3200 let PI2 = 6.28318530718;
3201 x = math_fmod(x, PI2);
3202 if x > 3.14159265 { x = x - PI2; }
3203 let x2 = x * x;
3204 let x4 = x2 * x2;
3205 let x6 = x4 * x2;
3206 return 1.0 - (x2 / 2.0) + (x4 / 24.0) - (x6 / 720.0);
3207 }
3208
3209 fn mat4_identity() -> Mat4 {
3210 let mut mat: Mat4;
3211 for i in 0..4 { for j in 0..4 { mat.m[i][j] = 0.0; } }
3212 mat.m[0][0] = 1.0; mat.m[1][1] = 1.0; mat.m[2][2] = 1.0; mat.m[3][3] = 1.0;
3213 return mat;
3214 }
3215
3216 fn mat4_mul(a: ptr<Mat4>, b: ptr<Mat4>) -> Mat4 {
3217 let mut res: Mat4;
3218 for c in 0..4 {
3219 for r in 0..4 {
3220 res.m[r][c] = (*a).m[r][0] * (*b).m[0][c] + (*a).m[r][1] * (*b).m[1][c] + (*a).m[r][2] * (*b).m[2][c] + (*a).m[r][3] * (*b).m[3][c];
3221 }
3222 }
3223 return res;
3224 }
3225
3226 fn mat4_make_rot_x(angle: f32) -> Mat4 {
3227 let mut mat = mat4_identity();
3228 let c = taylor_cos(angle); let s = taylor_sin(angle);
3229 mat.m[1][1] = c; mat.m[1][2] = -s;
3230 mat.m[2][1] = s; mat.m[2][2] = c;
3231 return mat;
3232 }
3233
3234 fn mat4_make_rot_y(angle: f32) -> Mat4 {
3235 let mut mat = mat4_identity();
3236 let c = taylor_cos(angle); let s = taylor_sin(angle);
3237 mat.m[0][0] = c; mat.m[0][2] = s;
3238 mat.m[2][0] = -s; mat.m[2][2] = c;
3239 return mat;
3240 }
3241
3242 fn mat4_make_rot_z(angle: f32) -> Mat4 {
3243 let mut mat = mat4_identity();
3244 let c = taylor_cos(angle); let s = taylor_sin(angle);
3245 mat.m[0][0] = c; mat.m[0][1] = -s;
3246 mat.m[1][0] = s; mat.m[1][1] = c;
3247 return mat;
3248 }
3249
3250 fn mat4_make_proj(fov: f32, aspect: f32, near: f32, far: f32) -> Mat4 {
3251 let f = 1.0 / taylor_sin(fov * 0.5) / taylor_cos(fov * 0.5);
3252 let mut mat: Mat4;
3253 for i in 0..4 { for j in 0..4 { mat.m[i][j] = 0.0; } }
3254 mat.m[0][0] = f / aspect;
3255 mat.m[1][1] = f;
3256 mat.m[2][2] = far / (far - near);
3257 mat.m[2][3] = (-far * near) / (far - near);
3258 mat.m[3][2] = 1.0;
3259 return mat;
3260 }
3261
3262 fn mat4_multiply_vec(m: ptr<Mat4>, i: ptr<Vec3>) -> Vec3 {
3263 let mut v: Vec3;
3264 v.x = (*i).x * (*m).m[0][0] + (*i).y * (*m).m[0][1] + (*i).z * (*m).m[0][2] + (*i).w * (*m).m[0][3];
3265 v.y = (*i).x * (*m).m[1][0] + (*i).y * (*m).m[1][1] + (*i).z * (*m).m[1][2] + (*i).w * (*m).m[1][3];
3266 v.z = (*i).x * (*m).m[2][0] + (*i).y * (*m).m[2][1] + (*i).z * (*m).m[2][2] + (*i).w * (*m).m[2][3];
3267 v.w = (*i).x * (*m).m[3][0] + (*i).y * (*m).m[3][1] + (*i).z * (*m).m[3][2] + (*i).w * (*m).m[3][3];
3268 return v;
3269 }
3270
3271 struct Triangle3D { p: [Vec3; 3], color: u32 }
3272 struct Mesh3D { tris: ptr<Triangle3D>, count: u32 }
3273
3274 let mut z_buffer: ptr<f32>;
3275
3276 fn render_init_3d(w: u32, h: u32) {
3277 z_buffer = pmm_alloc_blocks((w * h * 4) / PAGE_SIZE + 1) as ptr<f32>;
3278 }
3279
3280 fn render_clear_z_buffer(w: u32, h: u32) {
3281 for i in 0..(w * h) { *(z_buffer as u64 + i as u64 * 4) as ptr<f32> = 0.0; }
3282 }
3283
3284 fn draw_flat_triangle(win: ptr<CompositorWindow>, x0: i32, y0: i32, z0: f32, x1: i32, y1: i32, z1: f32, x2: i32, y2: i32, z2: f32, color: u32) {
3285 let mut min_y = y0; if y1 < min_y { min_y = y1; } if y2 < min_y { min_y = y2; }
3286 let mut max_y = y0; if y1 > max_y { max_y = y1; } if y2 > max_y { max_y = y2; }
3287 let mut min_x = x0; if x1 < min_x { min_x = x1; } if x2 < min_x { min_x = x2; }
3288 let mut max_x = x0; if x1 > max_x { max_x = x1; } if x2 > max_x { max_x = x2; }
3289
3290 if min_x < 0 { min_x = 0; }
3291 if min_y < 0 { min_y = 0; }
3292 if max_x >= (*win).width as i32 { max_x = (*win).width as i32 - 1; }
3293 if max_y >= (*win).height as i32 { max_y = (*win).height as i32 - 1; }
3294
3295 let buf = (*win).buffer_phys as ptr<u32>;
3296 let z_ptr = z_buffer;
3297
3298 for y in min_y..=max_y {
3299 for x in min_x..=max_x {
3300 let w0 = ((x1 - x0) * (y - y0) - (y1 - y0) * (x - x0)) as f32;
3301 let w1 = ((x2 - x1) * (y - y1) - (y2 - y1) * (x - x1)) as f32;
3302 let w2 = ((x0 - x2) * (y - y2) - (y0 - y2) * (x - x2)) as f32;
3303
3304 if (w0 >= 0.0 && w1 >= 0.0 && w2 >= 0.0) || (w0 <= 0.0 && w1 <= 0.0 && w2 <= 0.0) {
3305 let area = w0 + w1 + w2;
3306 let b0 = w1 / area; let b1 = w2 / area; let b2 = w0 / area;
3307 let z = z0 * b0 + z1 * b1 + z2 * b2;
3308 let z_idx = (y * (*win).width as i32 + x) as u64;
3309 let current_z = *(z_ptr as u64 + z_idx * 4) as ptr<f32>;
3310
3311 if z > *current_z {
3312 *current_z = z;
3313 *(buf + z_idx) = color;
3314 }
3315 }
3316 }
3317 }
3318 }
3319
3320 fn render_mesh(win: ptr<CompositorWindow>, mesh: ptr<Mesh3D>, mat_world: ptr<Mat4>, mat_proj: ptr<Mat4>) {
3321 for i in 0..(*mesh).count {
3322 let tri = ((*mesh).tris as u64 + i as u64 * sizeof(Triangle3D) as u64) as ptr<Triangle3D>;
3323 let mut tri_proj: Triangle3D;
3324 let mut tri_trans: Triangle3D;
3325
3326 for j in 0..3 {
3327 tri_trans.p[j] = mat4_multiply_vec(mat_world, &(*tri).p[j] as ptr<Vec3>);
3328 tri_proj.p[j] = mat4_multiply_vec(mat_proj, &tri_trans.p[j] as ptr<Vec3>);
3329
3330 if tri_proj.p[j].w != 0.0 {
3331 tri_proj.p[j].x = tri_proj.p[j].x / tri_proj.p[j].w;
3332 tri_proj.p[j].y = tri_proj.p[j].y / tri_proj.p[j].w;
3333 tri_proj.p[j].z = tri_proj.p[j].z / tri_proj.p[j].w;
3334 }
3335
3336 tri_proj.p[j].x = (tri_proj.p[j].x + 1.0) * 0.5 * (*win).width as f32;
3337 tri_proj.p[j].y = (tri_proj.p[j].y + 1.0) * 0.5 * (*win).height as f32;
3338 }
3339
3340 let normal_x = (tri_trans.p[1].y - tri_trans.p[0].y) * (tri_trans.p[2].z - tri_trans.p[0].z) - (tri_trans.p[1].z - tri_trans.p[0].z) * (tri_trans.p[2].y - tri_trans.p[0].y);
3341 let normal_y = (tri_trans.p[1].z - tri_trans.p[0].z) * (tri_trans.p[2].x - tri_trans.p[0].x) - (tri_trans.p[1].x - tri_trans.p[0].x) * (tri_trans.p[2].z - tri_trans.p[0].z);
3342 let normal_z = (tri_trans.p[1].x - tri_trans.p[0].x) * (tri_trans.p[2].y - tri_trans.p[0].y) - (tri_trans.p[1].y - tri_trans.p[0].y) * (tri_trans.p[2].x - tri_trans.p[0].x);
3343
3344 if normal_x * tri_trans.p[0].x + normal_y * tri_trans.p[0].y + normal_z * tri_trans.p[0].z < 0.0 {
3345 let shade = math_abs(normal_z) * 255.0;
3346 let c_r = (((*tri).color >> 16) & 0xFF) as f32 * shade / 255.0;
3347 let c_g = (((*tri).color >> 8) & 0xFF) as f32 * shade / 255.0;
3348 let c_b = ((*tri).color & 0xFF) as f32 * shade / 255.0;
3349 let shaded_color = ((c_r as u32) << 16) | ((c_g as u32) << 8) | (c_b as u32);
3350
3351 draw_flat_triangle(win, tri_proj.p[0].x as i32, tri_proj.p[0].y as i32, tri_proj.p[0].z,
3352 tri_proj.p[1].x as i32, tri_proj.p[1].y as i32, tri_proj.p[1].z,
3353 tri_proj.p[2].x as i32, tri_proj.p[2].y as i32, tri_proj.p[2].z, shaded_color);
3354 }
3355 }
3356 }
3357
3358 let mut prng_state: u64 = 0x8817263544132211;
3359
3360 fn rand_next() -> u64 {
3361 prng_state ^= prng_state << 13;
3362 prng_state ^= prng_state >> 7;
3363 prng_state ^= prng_state << 17;
3364 return prng_state;
3365 }
3366
3367 fn rand_seed(seed: u64) {
3368 if seed != 0 { prng_state = seed; }
3369 }
3370
3371 fn strchr(str: ptr<u8>, c: u8) -> ptr<u8> {
3372 let mut i: u64 = 0;
3373 while *(str + i) != 0 {
3374 if *(str + i) == c { return (str as u64 + i) as ptr<u8>; }
3375 i = i + 1;
3376 }
3377 if c == 0 { return (str as u64 + i) as ptr<u8>; }
3378 return 0 as ptr<u8>;
3379 }
3380
3381 fn strcat(dest: ptr<u8>, src: ptr<u8>) {
3382 let mut i: u64 = 0;
3383 while *(dest + i) != 0 { i = i + 1; }
3384 let mut j: u64 = 0;
3385 while *(src + j) != 0 {
3386 *(dest + i + j) = *(src + j);
3387 j = j + 1;
3388 }
3389 *(dest + i + j) = 0;
3390 }
3391
3392 fn strncmp(s1: ptr<u8>, s2: ptr<u8>, n: u64) -> i32 {
3393 for i in 0..n {
3394 if *(s1 + i) == 0 || *(s1 + i) != *(s2 + i) {
3395 return (*(s1 + i) - *(s2 + i)) as i32;
3396 }
3397 }
3398 return 0;
3399 }
3400
3401 fn atoi(str: ptr<u8>) -> i32 {
3402 let mut res: i32 = 0;
3403 let mut sign: i32 = 1;
3404 let mut i: u64 = 0;
3405 if *(str + i) == '-' as u8 {
3406 sign = -1;
3407 i = i + 1;
3408 }
3409 while *(str + i) >= '0' as u8 && *(str + i) <= '9' as u8 {
3410 res = res * 10 + (*(str + i) - '0' as u8) as i32;
3411 i = i + 1;
3412 }
3413 return res * sign;
3414 }
3415
3416 fn itoa(val: i32, base: i32, buf: ptr<u8>) {
3417 let mut i: u64 = 0;
3418 let mut is_neg = false;
3419 let mut num = val;
3420 if num == 0 {
3421 *(buf + i) = '0' as u8;
3422 *(buf + i + 1) = 0;
3423 return;
3424 }
3425 if num < 0 && base == 10 {
3426 is_neg = true;
3427 num = -num;
3428 }
3429 while num != 0 {
3430 let rem = num % base;
3431 if rem > 9 {
3432 *(buf + i) = (rem - 10 + 'a' as i32) as u8;
3433 } else {
3434 *(buf + i) = (rem + '0' as i32) as u8;
3435 }
3436 i = i + 1;
3437 num = num / base;
3438 }
3439 if is_neg {
3440 *(buf + i) = '-' as u8;
3441 i = i + 1;
3442 }
3443 *(buf + i) = 0;
3444 let mut start: u64 = 0;
3445 let mut end: u64 = i - 1;
3446 while start < end {
3447 let temp = *(buf + start);
3448 *(buf + start) = *(buf + end);
3449 *(buf + end) = temp;
3450 start = start + 1;
3451 end = end - 1;
3452 }
3453 }
3454
3455 let mut b64_table: ptr<u8> = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" as ptr<u8>;
3456
3457 fn base64_encode(src: ptr<u8>, len: u64, out: ptr<u8>) {
3458 let mut i: u64 = 0;
3459 let mut j: u64 = 0;
3460 while i < len {
3461 let octet_a = if i < len { *(src + i) } else { 0 };
3462 let octet_b = if i + 1 < len { *(src + i + 1) } else { 0 };
3463 let octet_c = if i + 2 < len { *(src + i + 2) } else { 0 };
3464 let triple = ((octet_a as u32) << 16) + ((octet_b as u32) << 8) + (octet_c as u32);
3465 *(out + j) = *(b64_table + ((triple >> 18) & 0x3F) as u64);
3466 *(out + j + 1) = *(b64_table + ((triple >> 12) & 0x3F) as u64);
3467 *(out + j + 2) = if i + 1 < len { *(b64_table + ((triple >> 6) & 0x3F) as u64) } else { '=' as u8 };
3468 *(out + j + 3) = if i + 2 < len { *(b64_table + (triple & 0x3F) as u64) } else { '=' as u8 };
3469 i = i + 3;
3470 j = j + 4;
3471 }
3472 *(out + j) = 0;
3473 }
3474
3475 fn tcp_accept(sock: ptr<TcpSocket>) -> ptr<TcpSocket> {
3476 spin_lock(&((*sock).lock));
3477 if (*sock).state == TCP_STATE_SYN_RCVD {
3478 let new_sock = tcp_create_socket();
3479 if new_sock != 0 as ptr<TcpSocket> {
3480 (*new_sock).state = TCP_STATE_ESTABLISHED;
3481 (*new_sock).local_port = (*sock).local_port;
3482 (*new_sock).remote_port = (*sock).remote_port;
3483 (*new_sock).remote_ip = (*sock).remote_ip;
3484 (*new_sock).seq_num = (*sock).seq_num;
3485 (*new_sock).ack_num = (*sock).ack_num;
3486 (*sock).state = TCP_STATE_LISTEN;
3487 spin_unlock(&((*sock).lock));
3488 return new_sock;
3489 }
3490 }
3491 spin_unlock(&((*sock).lock));
3492 return 0 as ptr<TcpSocket>;
3493 }
3494
3495 fn tcp_receive(sock: ptr<TcpSocket>, buffer: ptr<u8>, max_len: u32) -> u32 {
3496 spin_lock(&((*sock).lock));
3497 let mut bytes_read: u32 = 0;
3498 while (*sock).rx_head != (*sock).rx_tail && bytes_read < max_len {
3499 *(buffer + bytes_read as u64) = *((*sock).rx_buffer as u64 + (*sock).rx_tail as u64) as ptr<u8>;
3500 (*sock).rx_tail = ((*sock).rx_tail + 1) % (PAGE_SIZE as u32 * 2);
3501 bytes_read = bytes_read + 1;
3502 }
3503 spin_unlock(&((*sock).lock));
3504 return bytes_read;
3505 }
3506
3507 fn tcp_send_data(sock: ptr<TcpSocket>, data: ptr<u8>, len: u32) {
3508 spin_lock(&((*sock).lock));
3509 if (*sock).state == TCP_STATE_ESTABLISHED {
3510 tcp_send_segment(sock, 0x0018, data, len as u16);
3511 (*sock).seq_num = (*sock).seq_num + len;
3512 }
3513 spin_unlock(&((*sock).lock));
3514 }
3515
3516 let mut http_200_hdr: ptr<u8> = "HTTP/1.1 200 OK\r\nServer: Aegis-X/1.0\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n" as ptr<u8>;
3517 let mut http_404_hdr: ptr<u8> = "HTTP/1.1 404 Not Found\r\nServer: Aegis-X/1.0\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n" as ptr<u8>;
3518 let mut http_index_html: ptr<u8> = "<html><head><title>YBG13 Aegis-X</title></head><body style='background-color:#111;color:#0f0;font-family:monospace;'><h1>Aegis-X Web Server Running</h1><p>Welcome to the 64-bit OS Web Interface.</p><hr><p>Powered by CHT-Core</p></body></html>" as ptr<u8>;
3519
3520 fn http_handle_client(client_sock: ptr<TcpSocket>) {
3521 let req_buf = pmm_alloc_blocks(1) as ptr<u8>;
3522 memset(req_buf, 0, PAGE_SIZE);
3523 let mut wait_timeout = 10000;
3524 let mut req_len: u32 = 0;
3525 while wait_timeout > 0 {
3526 let r = tcp_receive(client_sock, (req_buf as u64 + req_len as u64) as ptr<u8>, PAGE_SIZE as u32 - req_len);
3527 req_len = req_len + r;
3528 if req_len > 4 {
3529 if *(req_buf as u64 + req_len as u64 - 1) as ptr<u8> == 10 && *(req_buf as u64 + req_len as u64 - 3) as ptr<u8> == 10 {
3530 break;
3531 }
3532 }
3533 wait_timeout = wait_timeout - 1;
3534 cpu_pause();
3535 }
3536
3537 if req_len > 0 {
3538 if strncmp(req_buf, "GET / " as ptr<u8>, 6) == 0 {
3539 let res_buf = pmm_alloc_blocks(2) as ptr<u8>;
3540 memset(res_buf, 0, PAGE_SIZE * 2);
3541 strcpy(res_buf, http_200_hdr);
3542 strcat(res_buf, http_index_html);
3543 tcp_send_data(client_sock, res_buf, strlen(res_buf) as u32);
3544 pmm_free_blocks(res_buf as u64, 2);
3545 } else {
3546 let res_buf = pmm_alloc_blocks(1) as ptr<u8>;
3547 memset(res_buf, 0, PAGE_SIZE);
3548 strcpy(res_buf, http_404_hdr);
3549 strcat(res_buf, "<html><body><h1>404 File Not Found</h1></body></html>" as ptr<u8>);
3550 tcp_send_data(client_sock, res_buf, strlen(res_buf) as u32);
3551 pmm_free_blocks(res_buf as u64, 1);
3552 }
3553 }
3554
3555 tcp_close(client_sock);
3556 pmm_free_blocks(req_buf as u64, 1);
3557 (*current_process).state = 0;
3558 scheduler_tick();
3559 }
3560
3561 fn http_server_task() {
3562 let server_sock = tcp_create_socket();
3563 tcp_bind(server_sock, 80);
3564 tcp_listen(server_sock);
3565
3566 loop {
3567 let client_sock = tcp_accept(server_sock);
3568 if client_sock != 0 as ptr<TcpSocket> {
3569 let proc = create_process(http_handle_client as u64, true);
3570 let ctx = (*proc).context;
3571 (*ctx).rdi = client_sock as u64;
3572 }
3573 scheduler_tick();
3574 }
3575 }
3576
3577 struct ShellCtx {
3578 win: ptr<CompositorWindow>,
3579 cx: u32,
3580 cy: u32,
3581 buf: [u8; 512],
3582 pos: u32,
3583 cwd: [u8; 256],
3584 fg_color: u32,
3585 }
3586
3587 let mut global_shell: ptr<ShellCtx>;
3588
3589 fn shell_print_char(c: u8) {
3590 if c == 10 {
3591 (*global_shell).cx = 2;
3592 (*global_shell).cy = (*global_shell).cy + system_font_h + 2;
3593 } else if c == 8 {
3594 if (*global_shell).cx > 2 {
3595 (*global_shell).cx = (*global_shell).cx - system_font_w;
3596 gui_draw_char((*global_shell).win, ' ' as u8, (*global_shell).cx, (*global_shell).cy, (*global_shell).fg_color, 0x000000);
3597 }
3598 } else {
3599 gui_draw_char((*global_shell).win, c, (*global_shell).cx, (*global_shell).cy, (*global_shell).fg_color, 0x000000);
3600 (*global_shell).cx = (*global_shell).cx + system_font_w;
3601 if (*global_shell).cx >= (*(*global_shell).win).width - system_font_w {
3602 (*global_shell).cx = 2;
3603 (*global_shell).cy = (*global_shell).cy + system_font_h + 2;
3604 }
3605 }
3606 if (*global_shell).cy >= (*(*global_shell).win).height - system_font_h {
3607 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
3608 (*global_shell).cx = 2;
3609 (*global_shell).cy = 2;
3610 }
3611 }
3612
3613 fn shell_print_string(str: ptr<u8>) {
3614 let mut i: u64 = 0;
3615 while *(str + i) != 0 {
3616 shell_print_char(*(str + i));
3617 i = i + 1;
3618 }
3619 }
3620
3621 fn shell_draw_prompt() {
3622 (*global_shell).fg_color = 0x00FF00;
3623 shell_print_string("root@aegis-x:" as ptr<u8>);
3624 (*global_shell).fg_color = 0x00AFFF;
3625 shell_print_string(&((*global_shell).cwd[0]) as ptr<u8>);
3626 (*global_shell).fg_color = 0xFFFFFF;
3627 shell_print_string("# " as ptr<u8>);
3628 }
3629
3630 fn shell_cmd_clear() {
3631 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
3632 (*global_shell).cx = 2;
3633 (*global_shell).cy = 2;
3634 }
3635
3636 fn shell_cmd_help() {
3637 shell_print_string("Aegis-X Shell v1.0\n" as ptr<u8>);
3638 shell_print_string("Commands: help, clear, echo, ls, cat, uptime, reboot, poweroff\n" as ptr<u8>);
3639 }
3640
3641 fn shell_cmd_echo(args: ptr<u8>) {
3642 shell_print_string(args);
3643 shell_print_char(10);
3644 }
3645
3646 fn shell_cmd_uptime() {
3647 let mut buf: [u8; 32];
3648 let ticks = rtc_tick;
3649 shell_print_string("Uptime: " as ptr<u8>);
3650 itoa(ticks as i32, 10, &buf[0] as ptr<u8>);
3651 shell_print_string(&buf[0] as ptr<u8>);
3652 shell_print_string(" ticks\n" as ptr<u8>);
3653 }
3654
3655 fn shell_cmd_ls(args: ptr<u8>) {
3656 let mut path = &((*global_shell).cwd[0]) as ptr<u8>;
3657 if *args != 0 { path = args; }
3658 let dir = vfs_find_child(global_vfs_root, path);
3659 if dir == 0 as ptr<VfsNode> {
3660 shell_print_string("ls: cannot access path\n" as ptr<u8>);
3661 return;
3662 }
3663 if ((*dir).flags & 0x07) != 0 {
3664 let mut curr = (*dir).children;
3665 while curr != 0 as ptr<VfsNode> {
3666 if ((*curr).flags & 0x07) != 0 {
3667 (*global_shell).fg_color = 0x00AFFF;
3668 } else {
3669 (*global_shell).fg_color = 0xFFFFFF;
3670 }
3671 shell_print_string(&((*curr).name[0]) as ptr<u8>);
3672 shell_print_string(" " as ptr<u8>);
3673 curr = (*curr).next;
3674 }
3675 shell_print_char(10);
3676 } else {
3677 shell_print_string(&((*dir).name[0]) as ptr<u8>);
3678 shell_print_char(10);
3679 }
3680 (*global_shell).fg_color = 0xFFFFFF;
3681 }
3682
3683 fn shell_execute() {
3684 let mut cmd_buf: [u8; 512];
3685 memcpy(&cmd_buf[0] as ptr<u8>, &((*global_shell).buf[0]) as ptr<u8>, (*global_shell).pos as u64);
3686 cmd_buf[(*global_shell).pos as usize] = 0;
3687
3688 let mut i: u32 = 0;
3689 while cmd_buf[i as usize] != 0 && cmd_buf[i as usize] != ' ' as u8 { i = i + 1; }
3690 if cmd_buf[i as usize] == ' ' as u8 {
3691 cmd_buf[i as usize] = 0;
3692 i = i + 1;
3693 }
3694 let args = (&cmd_buf[0] as u64 + i as u64) as ptr<u8>;
3695 let cmd = &cmd_buf[0] as ptr<u8>;
3696
3697 if (*global_shell).pos > 0 {
3698 if strcmp(cmd, "help" as ptr<u8>) == 0 { shell_cmd_help(); }
3699 else if strcmp(cmd, "clear" as ptr<u8>) == 0 { shell_cmd_clear(); }
3700 else if strcmp(cmd, "echo" as ptr<u8>) == 0 { shell_cmd_echo(args); }
3701 else if strcmp(cmd, "uptime" as ptr<u8>) == 0 { shell_cmd_uptime(); }
3702 else if strcmp(cmd, "ls" as ptr<u8>) == 0 { shell_cmd_ls(args); }
3703 else if strcmp(cmd, "reboot" as ptr<u8>) == 0 { acpi_reset(); }
3704 else if strcmp(cmd, "poweroff" as ptr<u8>) == 0 { acpi_power_off(); }
3705 else {
3706 shell_print_string("Command not found: " as ptr<u8>);
3707 shell_print_string(cmd);
3708 shell_print_char(10);
3709 }
3710 }
3711
3712 (*global_shell).pos = 0;
3713 shell_draw_prompt();
3714 }
3715
3716 fn shell_task() {
3717 let win = comp_create_window(50, 50, 800, 600, "Aegis Terminal" as ptr<u8>);
3718 comp_draw_rect(win, 0, 0, (*win).width, (*win).height, 0x000000);
3719
3720 global_shell = pmm_alloc_blocks(1) as ptr<ShellCtx>;
3721 memset(global_shell as ptr<u8>, 0, sizeof(ShellCtx) as u64);
3722 (*global_shell).win = win;
3723 (*global_shell).cx = 2;
3724 (*global_shell).cy = 2;
3725 (*global_shell).fg_color = 0xFFFFFF;
3726 strcpy(&((*global_shell).cwd[0]) as ptr<u8>, "/" as ptr<u8>);
3727
3728 shell_print_string("Welcome to YBG13 Aegis-X Terminal.\n" as ptr<u8>);
3729 shell_draw_prompt();
3730
3731 loop {
3732 let c = kbd_read();
3733 if c != 0 {
3734 if c == 10 {
3735 shell_print_char(10);
3736 shell_execute();
3737 } else if c == 8 {
3738 if (*global_shell).pos > 0 {
3739 (*global_shell).pos = (*global_shell).pos - 1;
3740 shell_print_char(8);
3741 }
3742 } else {
3743 if (*global_shell).pos < 510 {
3744 (*global_shell).buf[(*global_shell).pos as usize] = c;
3745 (*global_shell).pos = (*global_shell).pos + 1;
3746 shell_print_char(c);
3747 }
3748 }
3749 }
3750 scheduler_tick();
3751 }
3752 }
3753
3754 struct VmaNode {
3755 start_vaddr: u64,
3756 end_vaddr: u64,
3757 flags: u32,
3758 file_node: ptr<VfsNode>,
3759 file_offset: u64,
3760 next: ptr<VmaNode>,
3761 }
3762
3763 struct ProcessMemoryMap {
3764 vma_head: ptr<VmaNode>,
3765 brk_start: u64,
3766 brk_current: u64,
3767 stack_bottom: u64,
3768 stack_top: u64,
3769 mmap_base: u64,
3770 }
3771
3772 fn vma_create(proc_map: ptr<ProcessMemoryMap>, start: u64, len: u64, flags: u32, file: ptr<VfsNode>, offset: u64) -> ptr<VmaNode> {
3773 let node = pmm_alloc_blocks(1) as ptr<VmaNode>;
3774 memset(node as ptr<u8>, 0, sizeof(VmaNode) as u64);
3775 (*node).start_vaddr = start;
3776 (*node).end_vaddr = start + len;
3777 (*node).flags = flags;
3778 (*node).file_node = file;
3779 (*node).file_offset = offset;
3780
3781 if (*proc_map).vma_head == 0 as ptr<VmaNode> {
3782 (*proc_map).vma_head = node;
3783 } else {
3784 let mut curr = (*proc_map).vma_head;
3785 while (*curr).next != 0 as ptr<VmaNode> {
3786 curr = (*curr).next;
3787 }
3788 (*curr).next = node;
3789 }
3790 return node;
3791 }
3792
3793 fn vma_find_region(proc_map: ptr<ProcessMemoryMap>, vaddr: u64) -> ptr<VmaNode> {
3794 let mut curr = (*proc_map).vma_head;
3795 while curr != 0 as ptr<VmaNode> {
3796 if vaddr >= (*curr).start_vaddr && vaddr < (*curr).end_vaddr {
3797 return curr;
3798 }
3799 curr = (*curr).next;
3800 }
3801 return 0 as ptr<VmaNode>;
3802 }
3803
3804 struct TarHeader {
3805 filename: [u8; 100],
3806 filemode: [u8; 8],
3807 owner_id: [u8; 8],
3808 group_id: [u8; 8],
3809 filesize: [u8; 12],
3810 last_mod: [u8; 12],
3811 checksum: [u8; 8],
3812 type_flag: u8,
3813 linked_file: [u8; 100],
3814 ustar_magic: [u8; 6],
3815 ustar_version: [u8; 2],
3816 owner_name: [u8; 32],
3817 group_name: [u8; 32],
3818 dev_major: [u8; 8],
3819 dev_minor: [u8; 8],
3820 prefix: [u8; 155],
3821 padding: [u8; 12],
3822 }
3823
3824 fn tar_octal_to_int(octal_str: ptr<u8>, len: u32) -> u64 {
3825 let mut result: u64 = 0;
3826 for i in 0..len {
3827 let c = *(octal_str + i as u64);
3828 if c >= '0' as u8 && c <= '7' as u8 {
3829 result = result * 8 + (c - '0' as u8) as u64;
3830 } else {
3831 break;
3832 }
3833 }
3834 return result;
3835 }
3836
3837 fn tar_extract_initramfs(ramfs_base: u64, ramfs_size: u64) {
3838 let mut current_offset: u64 = 0;
3839 while current_offset < ramfs_size {
3840 let header = (ramfs_base + current_offset) as ptr<TarHeader>;
3841 if (*header).filename[0] == 0 { break; }
3842
3843 let size_val = tar_octal_to_int(&((*header).filesize[0]) as ptr<u8>, 11);
3844 let mode_val = tar_octal_to_int(&((*header).filemode[0]) as ptr<u8>, 7);
3845 let mut name_buf: [u8; 256];
3846 memset(&name_buf[0] as ptr<u8>, 0, 256);
3847
3848 if (*header).prefix[0] != 0 {
3849 strcpy(&name_buf[0] as ptr<u8>, &((*header).prefix[0]) as ptr<u8>);
3850 strcat(&name_buf[0] as ptr<u8>, "/" as ptr<u8>);
3851 }
3852 strcat(&name_buf[0] as ptr<u8>, &((*header).filename[0]) as ptr<u8>);
3853
3854 let file_data_ptr = ramfs_base + current_offset + 512;
3855
3856 if (*header).type_flag == '0' as u8 || (*header).type_flag == 0 {
3857 let mut fd: FileDescriptor;
3858 let node = vfs_create_node(global_vfs_root, &name_buf[0] as ptr<u8>, 0x06);
3859 (*node).ptr = file_data_ptr;
3860 (*node).length = size_val;
3861 (*node).uid = 0;
3862 (*node).gid = 0;
3863 } else if (*header).type_flag == '5' as u8 {
3864 vfs_create_node(global_vfs_root, &name_buf[0] as ptr<u8>, 0x07);
3865 }
3866
3867 let aligned_size = (size_val + 511) & !511;
3868 current_offset = current_offset + 512 + aligned_size;
3869 }
3870 }
3871
3872 const REG_TYPE_INT: u32 = 1;
3873 const REG_TYPE_STR: u32 = 2;
3874 const REG_TYPE_BIN: u32 = 3;
3875
3876 struct RegistryNode {
3877 key_name: [u8; 64],
3878 val_type: u32,
3879 val_int: u64,
3880 val_str: [u8; 256],
3881 val_bin: ptr<u8>,
3882 bin_len: u64,
3883 parent: ptr<RegistryNode>,
3884 child: ptr<RegistryNode>,
3885 next: ptr<RegistryNode>,
3886 }
3887
3888 let mut global_registry_root: ptr<RegistryNode>;
3889
3890 fn registry_init() {
3891 global_registry_root = pmm_alloc_blocks(1) as ptr<RegistryNode>;
3892 memset(global_registry_root as ptr<u8>, 0, sizeof(RegistryNode) as u64);
3893 strcpy(&((*global_registry_root).key_name[0]) as ptr<u8>, "ROOT" as ptr<u8>);
3894 }
3895
3896 fn registry_create_key(parent: ptr<RegistryNode>, name: ptr<u8>) -> ptr<RegistryNode> {
3897 let node = pmm_alloc_blocks(1) as ptr<RegistryNode>;
3898 memset(node as ptr<u8>, 0, sizeof(RegistryNode) as u64);
3899 strcpy(&((*node).key_name[0]) as ptr<u8>, name);
3900 (*node).parent = parent;
3901
3902 if (*parent).child == 0 as ptr<RegistryNode> {
3903 (*parent).child = node;
3904 } else {
3905 let mut curr = (*parent).child;
3906 while (*curr).next != 0 as ptr<RegistryNode> {
3907 curr = (*curr).next;
3908 }
3909 (*curr).next = node;
3910 }
3911 return node;
3912 }
3913
3914 fn registry_find_key(parent: ptr<RegistryNode>, name: ptr<u8>) -> ptr<RegistryNode> {
3915 let mut curr = (*parent).child;
3916 while curr != 0 as ptr<RegistryNode> {
3917 if strcmp(&((*curr).key_name[0]) as ptr<u8>, name) == 0 {
3918 return curr;
3919 }
3920 curr = (*curr).next;
3921 }
3922 return 0 as ptr<RegistryNode>;
3923 }
3924
3925 fn registry_set_int(node: ptr<RegistryNode>, val: u64) {
3926 (*node).val_type = REG_TYPE_INT;
3927 (*node).val_int = val;
3928 }
3929
3930 fn registry_set_str(node: ptr<RegistryNode>, val: ptr<u8>) {
3931 (*node).val_type = REG_TYPE_STR;
3932 strcpy(&((*node).val_str[0]) as ptr<u8>, val);
3933 }
3934
3935 fn registry_set_bin(node: ptr<RegistryNode>, val: ptr<u8>, len: u64) {
3936 (*node).val_type = REG_TYPE_BIN;
3937 if (*node).val_bin != 0 as ptr<u8> {
3938 pmm_free_blocks((*node).val_bin as u64, ((*node).bin_len / PAGE_SIZE) + 1);
3939 }
3940 (*node).val_bin = pmm_alloc_blocks((len / PAGE_SIZE) + 1) as ptr<u8>;
3941 memcpy((*node).val_bin, val, len);
3942 (*node).bin_len = len;
3943 }
3944
3945 struct UserAccount {
3946 uid: u32,
3947 gid: u32,
3948 username: [u8; 32],
3949 pass_hash: [u8; 32],
3950 pass_salt: [u8; 16],
3951 home_dir: [u8; 64],
3952 shell_path: [u8; 64],
3953 next: ptr<UserAccount>,
3954 }
3955
3956 let mut global_user_db: ptr<UserAccount>;
3957 let mut next_uid: u32 = 1000;
3958
3959 fn auth_init_system() {
3960 global_user_db = 0 as ptr<UserAccount>;
3961 let mut root_salt: [u8; 16];
3962 for i in 0..16 { root_salt[i] = (rand_next() & 0xFF) as u8; }
3963 auth_create_user("root" as ptr<u8>, "aegis_admin" as ptr<u8>, 0, 0, "/root" as ptr<u8>, "/bin/shell" as ptr<u8>);
3964 }
3965
3966 fn auth_generate_hash(password: ptr<u8>, salt: ptr<u8>, out_hash: ptr<u8>) {
3967 let mut pass_len = strlen(password);
3968 let mut buffer: [u8; 128];
3969 memset(&buffer[0] as ptr<u8>, 0, 128);
3970 memcpy(&buffer[0] as ptr<u8>, password, pass_len);
3971 memcpy((&buffer[0] as u64 + pass_len) as ptr<u8>, salt, 16);
3972
3973 let mut ctx: Sha256Ctx;
3974 sha256_init(&ctx);
3975 sha256_transform(&ctx, &buffer[0] as ptr<u8>);
3976
3977 for iter in 0..999 {
3978 let mut temp_ctx: Sha256Ctx;
3979 sha256_init(&temp_ctx);
3980 let state_ptr = &ctx.state[0] as ptr<u32> as ptr<u8>;
3981 sha256_transform(&temp_ctx, state_ptr);
3982 for i in 0..8 { ctx.state[i] = temp_ctx.state[i]; }
3983 }
3984
3985 let state_ptr = &ctx.state[0] as ptr<u32> as ptr<u8>;
3986 for i in 0..32 {
3987 *(out_hash + i) = *(state_ptr + i);
3988 }
3989 }
3990
3991 fn auth_create_user(username: ptr<u8>, password: ptr<u8>, uid_force: u32, gid: u32, home: ptr<u8>, shell: ptr<u8>) -> ptr<UserAccount> {
3992 let new_user = pmm_alloc_blocks(1) as ptr<UserAccount>;
3993 memset(new_user as ptr<u8>, 0, sizeof(UserAccount) as u64);
3994
3995 strcpy(&((*new_user).username[0]) as ptr<u8>, username);
3996 strcpy(&((*new_user).home_dir[0]) as ptr<u8>, home);
3997 strcpy(&((*new_user).shell_path[0]) as ptr<u8>, shell);
3998
3999 if uid_force != 0xFFFFFFFF {
4000 (*new_user).uid = uid_force;
4001 } else {
4002 (*new_user).uid = next_uid;
4003 next_uid = next_uid + 1;
4004 }
4005 (*new_user).gid = gid;
4006
4007 for i in 0..16 { (*new_user).pass_salt[i] = (rand_next() & 0xFF) as u8; }
4008 auth_generate_hash(password, &((*new_user).pass_salt[0]) as ptr<u8>, &((*new_user).pass_hash[0]) as ptr<u8>);
4009
4010 (*new_user).next = global_user_db;
4011 global_user_db = new_user;
4012 return new_user;
4013 }
4014
4015 fn auth_verify_login(username: ptr<u8>, password: ptr<u8>) -> ptr<UserAccount> {
4016 let mut curr = global_user_db;
4017 while curr != 0 as ptr<UserAccount> {
4018 if strcmp(&((*curr).username[0]) as ptr<u8>, username) == 0 {
4019 let mut test_hash: [u8; 32];
4020 auth_generate_hash(password, &((*curr).pass_salt[0]) as ptr<u8>, &test_hash[0] as ptr<u8>);
4021 if memcmp(&((*curr).pass_hash[0]) as ptr<u8>, &test_hash[0] as ptr<u8>, 32) == 0 {
4022 return curr;
4023 } else {
4024 return 0 as ptr<UserAccount>;
4025 }
4026 }
4027 curr = (*curr).next;
4028 }
4029 return 0 as ptr<UserAccount>;
4030 }
4031
4032 struct ServiceDaemon {
4033 name: [u8; 64],
4034 exec_path: [u8; 128],
4035 pid: u64,
4036 status: u32,
4037 runlevel: u32,
4038 restart_count: u32,
4039 deps: [u64; 8],
4040 dep_count: u32,
4041 next: ptr<ServiceDaemon>,
4042 }
4043
4044 const SRV_STATUS_STOPPED: u32 = 0;
4045 const SRV_STATUS_STARTING: u32 = 1;
4046 const SRV_STATUS_RUNNING: u32 = 2;
4047 const SRV_STATUS_FAILED: u32 = 3;
4048
4049 let mut global_service_list: ptr<ServiceDaemon>;
4050 let mut init_current_runlevel: u32 = 0;
4051
4052 fn init_register_service(name: ptr<u8>, path: ptr<u8>, runlevel: u32) -> ptr<ServiceDaemon> {
4053 let srv = pmm_alloc_blocks(1) as ptr<ServiceDaemon>;
4054 memset(srv as ptr<u8>, 0, sizeof(ServiceDaemon) as u64);
4055 strcpy(&((*srv).name[0]) as ptr<u8>, name);
4056 strcpy(&((*srv).exec_path[0]) as ptr<u8>, path);
4057 (*srv).status = SRV_STATUS_STOPPED;
4058 (*srv).runlevel = runlevel;
4059 (*srv).dep_count = 0;
4060
4061 (*srv).next = global_service_list;
4062 global_service_list = srv;
4063 return srv;
4064 }
4065
4066 fn init_add_dependency(srv: ptr<ServiceDaemon>, target_name: ptr<u8>) {
4067 let mut curr = global_service_list;
4068 while curr != 0 as ptr<ServiceDaemon> {
4069 if strcmp(&((*curr).name[0]) as ptr<u8>, target_name) == 0 {
4070 if (*srv).dep_count < 8 {
4071 (*srv).deps[(*srv).dep_count as usize] = curr as u64;
4072 (*srv).dep_count = (*srv).dep_count + 1;
4073 }
4074 return;
4075 }
4076 curr = (*curr).next;
4077 }
4078 }
4079
4080 fn init_start_service(srv: ptr<ServiceDaemon>) -> bool {
4081 if (*srv).status == SRV_STATUS_RUNNING { return true; }
4082
4083 for i in 0..(*srv).dep_count {
4084 let dep = (*srv).deps[i as usize] as ptr<ServiceDaemon>;
4085 if (*dep).status != SRV_STATUS_RUNNING {
4086 if !init_start_service(dep) {
4087 (*srv).status = SRV_STATUS_FAILED;
4088 return false;
4089 }
4090 }
4091 }
4092
4093 (*srv).status = SRV_STATUS_STARTING;
4094 let pid = execve_ring3(&((*srv).exec_path[0]) as ptr<u8>, 0, 0);
4095 if pid != 0 {
4096 (*srv).pid = pid;
4097 (*srv).status = SRV_STATUS_RUNNING;
4098 return true;
4099 } else {
4100 (*srv).status = SRV_STATUS_FAILED;
4101 return false;
4102 }
4103 }
4104
4105 fn init_set_runlevel(level: u32) {
4106 init_current_runlevel = level;
4107 let mut curr = global_service_list;
4108 while curr != 0 as ptr<ServiceDaemon> {
4109 if (*curr).runlevel <= level && (*curr).status == SRV_STATUS_STOPPED {
4110 init_start_service(curr);
4111 } else if (*curr).runlevel > level && (*curr).status == SRV_STATUS_RUNNING {
4112 let mut proc = process_queue;
4113 while proc != 0 as ptr<ProcessControlBlock> {
4114 if (*proc).pid == (*curr).pid {
4115 (*proc).state = 0;
4116 (*curr).status = SRV_STATUS_STOPPED;
4117 break;
4118 }
4119 proc = (*proc).next;
4120 }
4121 }
4122 curr = (*curr).next;
4123 }
4124 }
4125
4126 fn init_monitor_loop() {
4127 loop {
4128 let mut curr = global_service_list;
4129 while curr != 0 as ptr<ServiceDaemon> {
4130 if (*curr).status == SRV_STATUS_RUNNING {
4131 let mut is_alive = false;
4132 let mut proc = process_queue;
4133 while proc != 0 as ptr<ProcessControlBlock> {
4134 if (*proc).pid == (*curr).pid && (*proc).state == 1 {
4135 is_alive = true;
4136 break;
4137 }
4138 proc = (*proc).next;
4139 }
4140 if !is_alive {
4141 (*curr).status = SRV_STATUS_FAILED;
4142 (*curr).restart_count = (*curr).restart_count + 1;
4143 if (*curr).restart_count < 5 {
4144 init_start_service(curr);
4145 }
4146 }
4147 }
4148 curr = (*curr).next;
4149 }
4150 for i in 0..100000 { cpu_pause(); }
4151 scheduler_tick();
4152 }
4153 }
4154
4155 struct Ext2Superblock {
4156 s_inodes_count: u32,
4157 s_blocks_count: u32,
4158 s_r_blocks_count: u32,
4159 s_free_blocks_count: u32,
4160 s_free_inodes_count: u32,
4161 s_first_data_block: u32,
4162 s_log_block_size: u32,
4163 s_log_frag_size: i32,
4164 s_blocks_per_group: u32,
4165 s_frags_per_group: u32,
4166 s_inodes_per_group: u32,
4167 s_mtime: u32,
4168 s_wtime: u32,
4169 s_mnt_count: u16,
4170 s_max_mnt_count: i16,
4171 s_magic: u16,
4172 s_state: u16,
4173 s_errors: u16,
4174 s_minor_rev_level: u16,
4175 s_lastcheck: u32,
4176 s_checkinterval: u32,
4177 s_creator_os: u32,
4178 s_rev_level: u32,
4179 s_def_resuid: u16,
4180 s_def_resgid: u16,
4181 s_first_ino: u32,
4182 s_inode_size: u16,
4183 s_block_group_nr: u16,
4184 s_feature_compat: u32,
4185 s_feature_incompat: u32,
4186 s_feature_ro_compat: u32,
4187 s_uuid: [u8; 16],
4188 s_volume_name: [u8; 16],
4189 s_last_mounted: [u8; 64],
4190 s_algo_bitmap: u32,
4191 }
4192
4193 struct Ext2BlockGroupDesc {
4194 bg_block_bitmap: u32,
4195 bg_inode_bitmap: u32,
4196 bg_inode_table: u32,
4197 bg_free_blocks_count: u16,
4198 bg_free_inodes_count: u16,
4199 bg_used_dirs_count: u16,
4200 bg_pad: u16,
4201 bg_reserved: [u32; 3],
4202 }
4203
4204 struct Ext2Inode {
4205 i_mode: u16,
4206 i_uid: u16,
4207 i_size: u32,
4208 i_atime: u32,
4209 i_ctime: u32,
4210 i_mtime: u32,
4211 i_dtime: u32,
4212 i_gid: u16,
4213 i_links_count: u16,
4214 i_blocks: u32,
4215 i_flags: u32,
4216 i_osd1: u32,
4217 i_block: [u32; 15],
4218 i_generation: u32,
4219 i_file_acl: u32,
4220 i_dir_acl: u32,
4221 i_faddr: u32,
4222 i_osd2: [u32; 3],
4223 }
4224
4225 struct Ext2DirEntry {
4226 inode: u32,
4227 rec_len: u16,
4228 name_len: u8,
4229 file_type: u8,
4230 }
4231
4232 let mut ext2_sb: ptr<Ext2Superblock>;
4233 let mut ext2_bgdt: ptr<Ext2BlockGroupDesc>;
4234 let mut ext2_block_size: u32 = 0;
4235 let mut ext2_inodes_per_group: u32 = 0;
4236 let mut ext2_inode_size: u32 = 0;
4237 let mut ext2_partition_base: u64 = 0;
4238
4239 fn ext2_read_block(block_num: u32, buf: ptr<u8>) {
4240 let offset = ext2_partition_base + (block_num as u64 * ext2_block_size as u64);
4241 let dev_fd = pmm_alloc_blocks(1) as ptr<FileDescriptor>;
4242 (*dev_fd).node = vfs_find_child(global_vfs_root, "dev/sda1" as ptr<u8>);
4243 (*dev_fd).offset = offset;
4244 vfs_read(dev_fd, buf, ext2_block_size as u64);
4245 pmm_free_blocks(dev_fd as u64, 1);
4246 }
4247
4248 fn ext2_init(partition_base: u64) {
4249 ext2_partition_base = partition_base;
4250 let sb_buf = pmm_alloc_blocks(1) as ptr<u8>;
4251 let dev_fd = pmm_alloc_blocks(1) as ptr<FileDescriptor>;
4252 (*dev_fd).node = vfs_find_child(global_vfs_root, "dev/sda1" as ptr<u8>);
4253 (*dev_fd).offset = ext2_partition_base + 1024;
4254 vfs_read(dev_fd, sb_buf, 1024);
4255
4256 ext2_sb = sb_buf as ptr<Ext2Superblock>;
4257 if (*ext2_sb).s_magic != 0xEF53 {
4258 pmm_free_blocks(sb_buf as u64, 1);
4259 pmm_free_blocks(dev_fd as u64, 1);
4260 return;
4261 }
4262
4263 ext2_block_size = 1024 << (*ext2_sb).s_log_block_size;
4264 ext2_inodes_per_group = (*ext2_sb).s_inodes_per_group;
4265 if (*ext2_sb).s_rev_level == 0 {
4266 ext2_inode_size = 128;
4267 } else {
4268 ext2_inode_size = (*ext2_sb).s_inode_size as u32;
4269 }
4270
4271 let bgdt_block = if ext2_block_size == 1024 { 2 } else { 1 };
4272 let bgdt_buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
4273 ext2_read_block(bgdt_block, bgdt_buf);
4274 ext2_bgdt = bgdt_buf as ptr<Ext2BlockGroupDesc>;
4275
4276 pmm_free_blocks(dev_fd as u64, 1);
4277 }
4278
4279 fn ext2_get_inode(inode_num: u32, out_inode: ptr<Ext2Inode>) {
4280 let bg_idx = (inode_num - 1) / ext2_inodes_per_group;
4281 let local_idx = (inode_num - 1) % ext2_inodes_per_group;
4282 let bgd = (ext2_bgdt as u64 + bg_idx as u64 * sizeof(Ext2BlockGroupDesc) as u64) as ptr<Ext2BlockGroupDesc>;
4283
4284 let inode_table_block = (*bgd).bg_inode_table;
4285 let byte_offset = local_idx * ext2_inode_size;
4286 let block_offset = byte_offset / ext2_block_size;
4287 let internal_offset = byte_offset % ext2_block_size;
4288
4289 let target_block = inode_table_block + block_offset;
4290 let buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
4291 ext2_read_block(target_block, buf);
4292
4293 memcpy(out_inode as ptr<u8>, (buf as u64 + internal_offset as u64) as ptr<u8>, sizeof(Ext2Inode) as u64);
4294 pmm_free_blocks(buf as u64, (ext2_block_size / PAGE_SIZE as u32) + 1);
4295 }
4296
4297 fn ext2_read_inode_data(inode: ptr<Ext2Inode>, buf: ptr<u8>) {
4298 let blocks_to_read = ((*inode).i_size + ext2_block_size - 1) / ext2_block_size;
4299 let mut current_block = 0;
4300 while current_block < blocks_to_read && current_block < 12 {
4301 let physical_block = (*inode).i_block[current_block as usize];
4302 if physical_block != 0 {
4303 ext2_read_block(physical_block, (buf as u64 + current_block as u64 * ext2_block_size as u64) as ptr<u8>);
4304 }
4305 current_block = current_block + 1;
4306 }
4307 }
4308
4309 struct Elf64_Sym {
4310 st_name: u32,
4311 st_info: u8,
4312 st_other: u8,
4313 st_shndx: u16,
4314 st_value: u64,
4315 st_size: u64,
4316 }
4317
4318 struct Elf64_Rela {
4319 r_offset: u64,
4320 r_info: u64,
4321 r_addend: i64,
4322 }
4323
4324 struct Elf64_Dyn {
4325 d_tag: u64,
4326 d_val: u64,
4327 }
4328
4329 const DT_NULL: u64 = 0;
4330 const DT_NEEDED: u64 = 1;
4331 const DT_PLTRELSZ: u64 = 2;
4332 const DT_PLTGOT: u64 = 3;
4333 const DT_HASH: u64 = 4;
4334 const DT_STRTAB: u64 = 5;
4335 const DT_SYMTAB: u64 = 6;
4336 const DT_RELA: u64 = 7;
4337 const DT_RELASZ: u64 = 8;
4338 const DT_RELAENT: u64 = 9;
4339 const DT_STRSZ: u64 = 10;
4340 const DT_SYMENT: u64 = 11;
4341
4342 const R_X86_64_NONE: u64 = 0;
4343 const R_X86_64_64: u64 = 1;
4344 const R_X86_64_PC32: u64 = 2;
4345 const R_X86_64_GOT32: u64 = 3;
4346 const R_X86_64_PLT32: u64 = 4;
4347 const R_X86_64_COPY: u64 = 5;
4348 const R_X86_64_GLOB_DAT: u64 = 6;
4349 const R_X86_64_JUMP_SLOT: u64 = 7;
4350 const R_X86_64_RELATIVE: u64 = 8;
4351
4352 fn elf_resolve_dynamic(load_base: u64, dyn_table: ptr<Elf64_Dyn>) {
4353 let mut strtab: ptr<u8> = 0 as ptr<u8>;
4354 let mut symtab: ptr<Elf64_Sym> = 0 as ptr<Elf64_Sym>;
4355 let mut rela: ptr<Elf64_Rela> = 0 as ptr<Elf64_Rela>;
4356 let mut relasz: u64 = 0;
4357
4358 let mut curr = dyn_table;
4359 while (*curr).d_tag != DT_NULL {
4360 if (*curr).d_tag == DT_STRTAB { strtab = (load_base + (*curr).d_val) as ptr<u8>; }
4361 else if (*curr).d_tag == DT_SYMTAB { symtab = (load_base + (*curr).d_val) as ptr<Elf64_Sym>; }
4362 else if (*curr).d_tag == DT_RELA { rela = (load_base + (*curr).d_val) as ptr<Elf64_Rela>; }
4363 else if (*curr).d_tag == DT_RELASZ { relasz = (*curr).d_val; }
4364 curr = (curr as u64 + sizeof(Elf64_Dyn) as u64) as ptr<Elf64_Dyn>;
4365 }
4366
4367 if rela != 0 as ptr<Elf64_Rela> && symtab != 0 as ptr<Elf64_Sym> {
4368 let rela_count = relasz / sizeof(Elf64_Rela) as u64;
4369 for i in 0..rela_count {
4370 let rel = (rela as u64 + i * sizeof(Elf64_Rela) as u64) as ptr<Elf64_Rela>;
4371 let r_type = (*rel).r_info & 0xFFFFFFFF;
4372 let sym_idx = (*rel).r_info >> 32;
4373 let target_addr = (load_base + (*rel).r_offset) as ptr<u64>;
4374
4375 if r_type == R_X86_64_RELATIVE {
4376 *target_addr = (load_base as i64 + (*rel).r_addend) as u64;
4377 } else if r_type == R_X86_64_GLOB_DAT || r_type == R_X86_64_JUMP_SLOT || r_type == R_X86_64_64 {
4378 let sym = (symtab as u64 + sym_idx * sizeof(Elf64_Sym) as u64) as ptr<Elf64_Sym>;
4379 let sym_val = (*sym).st_value;
4380 if sym_val != 0 {
4381 *target_addr = (load_base + sym_val) as i64 as u64 + (*rel).r_addend as u64;
4382 }
4383 }
4384 }
4385 }
4386 }
4387
4388 struct AnsiState {
4389 in_escape: bool,
4390 in_bracket: bool,
4391 params: [u32; 8],
4392 param_count: u32,
4393 current_param: u32,
4394 saved_x: u32,
4395 saved_y: u32,
4396 }
4397
4398 let mut global_ansi_state: AnsiState;
4399
4400 fn ansi_init() {
4401 global_ansi_state.in_escape = false;
4402 global_ansi_state.in_bracket = false;
4403 global_ansi_state.param_count = 0;
4404 global_ansi_state.current_param = 0;
4405 global_ansi_state.saved_x = 0;
4406 global_ansi_state.saved_y = 0;
4407 }
4408
4409 fn ansi_apply_colors() {
4410 for i in 0..global_ansi_state.param_count {
4411 let p = global_ansi_state.params[i as usize];
4412 if p == 0 {
4413 (*global_shell).fg_color = 0xFFFFFF;
4414 } else if p >= 30 && p <= 37 {
4415 if p == 30 { (*global_shell).fg_color = 0x000000; }
4416 else if p == 31 { (*global_shell).fg_color = 0xFF0000; }
4417 else if p == 32 { (*global_shell).fg_color = 0x00FF00; }
4418 else if p == 33 { (*global_shell).fg_color = 0xFFFF00; }
4419 else if p == 34 { (*global_shell).fg_color = 0x0000FF; }
4420 else if p == 35 { (*global_shell).fg_color = 0xFF00FF; }
4421 else if p == 36 { (*global_shell).fg_color = 0x00FFFF; }
4422 else if p == 37 { (*global_shell).fg_color = 0xFFFFFF; }
4423 }
4424 }
4425 }
4426
4427 fn ansi_process_char(c: u8) -> bool {
4428 if c == 27 {
4429 global_ansi_state.in_escape = true;
4430 global_ansi_state.in_bracket = false;
4431 global_ansi_state.param_count = 0;
4432 global_ansi_state.current_param = 0;
4433 return true;
4434 }
4435 if global_ansi_state.in_escape {
4436 if !global_ansi_state.in_bracket {
4437 if c == '[' as u8 {
4438 global_ansi_state.in_bracket = true;
4439 } else {
4440 global_ansi_state.in_escape = false;
4441 }
4442 return true;
4443 }
4444
4445 if c >= '0' as u8 && c <= '9' as u8 {
4446 global_ansi_state.current_param = global_ansi_state.current_param * 10 + (c - '0' as u8) as u32;
4447 return true;
4448 } else if c == ';' as u8 {
4449 if global_ansi_state.param_count < 8 {
4450 global_ansi_state.params[global_ansi_state.param_count as usize] = global_ansi_state.current_param;
4451 global_ansi_state.param_count = global_ansi_state.param_count + 1;
4452 }
4453 global_ansi_state.current_param = 0;
4454 return true;
4455 } else {
4456 if global_ansi_state.param_count < 8 {
4457 global_ansi_state.params[global_ansi_state.param_count as usize] = global_ansi_state.current_param;
4458 global_ansi_state.param_count = global_ansi_state.param_count + 1;
4459 }
4460
4461 if c == 'm' as u8 {
4462 ansi_apply_colors();
4463 } else if c == 'H' as u8 || c == 'f' as u8 {
4464 let row = if global_ansi_state.param_count > 0 { global_ansi_state.params[0] } else { 1 };
4465 let col = if global_ansi_state.param_count > 1 { global_ansi_state.params[1] } else { 1 };
4466 (*global_shell).cx = col * system_font_w;
4467 (*global_shell).cy = row * system_font_h;
4468 } else if c == 'J' as u8 {
4469 if global_ansi_state.params[0] == 2 {
4470 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
4471 (*global_shell).cx = 2; (*global_shell).cy = 2;
4472 }
4473 }
4474
4475 global_ansi_state.in_escape = false;
4476 return true;
4477 }
4478 }
4479 return false;
4480 }
4481
4482 struct ShmSegment {
4483 shm_id: u64,
4484 key: u32,
4485 size: u64,
4486 phys_base: u64,
4487 ref_count: u32,
4488 owner_pid: u64,
4489 permissions: u32,
4490 }
4491
4492 let mut global_shm_table: [ShmSegment; 256];
4493 let mut shm_next_id: u64 = 100;
4494 let mut shm_lock: Spinlock;
4495
4496 fn shm_init() {
4497 spin_init(&shm_lock);
4498 for i in 0..256 {
4499 global_shm_table[i].shm_id = 0;
4500 }
4501 }
4502
4503 fn shm_create(key: u32, size: u64, permissions: u32, pid: u64) -> u64 {
4504 spin_lock(&shm_lock);
4505 for i in 0..256 {
4506 if global_shm_table[i].key == key && global_shm_table[i].shm_id != 0 {
4507 spin_unlock(&shm_lock);
4508 return global_shm_table[i].shm_id;
4509 }
4510 }
4511
4512 for i in 0..256 {
4513 if global_shm_table[i].shm_id == 0 {
4514 let pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
4515 let phys = pmm_alloc_blocks(pages);
4516 memset(phys as ptr<u8>, 0, pages * PAGE_SIZE);
4517
4518 global_shm_table[i].shm_id = shm_next_id;
4519 shm_next_id = shm_next_id + 1;
4520 global_shm_table[i].key = key;
4521 global_shm_table[i].size = size;
4522 global_shm_table[i].phys_base = phys;
4523 global_shm_table[i].ref_count = 0;
4524 global_shm_table[i].owner_pid = pid;
4525 global_shm_table[i].permissions = permissions;
4526
4527 spin_unlock(&shm_lock);
4528 return global_shm_table[i].shm_id;
4529 }
4530 }
4531 spin_unlock(&shm_lock);
4532 return 0;
4533 }
4534
4535 fn shm_attach(shm_id: u64, cr3: u64, vaddr_suggest: u64) -> u64 {
4536 spin_lock(&shm_lock);
4537 for i in 0..256 {
4538 if global_shm_table[i].shm_id == shm_id {
4539 let pages = (global_shm_table[i].size + PAGE_SIZE - 1) / PAGE_SIZE;
4540 let mut vaddr = vaddr_suggest;
4541 if vaddr == 0 { vaddr = 0x5000000000; }
4542
4543 let old_cr3 = rdmsr(0);
4544 asm { "mov cr3, %0" in "%0" = cr3; }
4545 for p in 0..pages {
4546 vmm_map_page(global_shm_table[i].phys_base + p * PAGE_SIZE, vaddr + p * PAGE_SIZE, 0x07);
4547 }
4548 asm { "mov cr3, %0" in "%0" = old_cr3; }
4549
4550 global_shm_table[i].ref_count = global_shm_table[i].ref_count + 1;
4551 spin_unlock(&shm_lock);
4552 return vaddr;
4553 }
4554 }
4555 spin_unlock(&shm_lock);
4556 return 0;
4557 }
4558
4559 struct ProcessStat {
4560 pid: u64,
4561 state: u8,
4562 time_slice: u64,
4563 vram_usage: u64,
4564 name: [u8; 32],
4565 }
4566
4567 fn get_system_stats(out_stats: ptr<ProcessStat>, max_count: u32) -> u32 {
4568 let mut count = 0;
4569 let mut curr = process_queue;
4570 while curr != 0 as ptr<ProcessControlBlock> && count < max_count {
4571 let stat = (out_stats as u64 + count as u64 * sizeof(ProcessStat) as u64) as ptr<ProcessStat>;
4572 (*stat).pid = (*curr).pid;
4573 (*stat).state = (*curr).state;
4574 (*stat).time_slice = (*curr).time_slice;
4575 (*stat).vram_usage = 0;
4576 count = count + 1;
4577 curr = (*curr).next;
4578 }
4579 return count;
4580 }
4581
4582 let mut loopback_mac: MacAddr;
4583 let mut loopback_ip: Ipv4Addr;
4584
4585 fn loopback_init() {
4586 for i in 0..6 { loopback_mac.addr[i] = 0; }
4587 loopback_ip.addr[0] = 127;
4588 loopback_ip.addr[1] = 0;
4589 loopback_ip.addr[2] = 0;
4590 loopback_ip.addr[3] = 1;
4591 }
4592
4593 fn loopback_send(packet: ptr<u8>, length: u32) {
4594 let rx_buffer = pmm_alloc_blocks((length as u64 / PAGE_SIZE) + 1) as ptr<u8>;
4595 memcpy(rx_buffer, packet, length as u64);
4596 pmm_free_blocks(rx_buffer as u64, (length as u64 / PAGE_SIZE) + 1);
4597 }
4598
4599 struct AegisContainer {
4600 container_id: u64,
4601 vfs_root: ptr<VfsNode>,
4602 pid_offset: u64,
4603 network_isolated: bool,
4604 virtual_ip: Ipv4Addr,
4605 memory_limit: u64,
4606 current_memory: u64,
4607 is_active: bool,
4608 name: [u8; 32],
4609 }
4610
4611 let mut global_containers: [AegisContainer; 64];
4612 let mut container_count: u64 = 1;
4613
4614 fn container_init() {
4615 for i in 0..64 {
4616 global_containers[i].is_active = false;
4617 }
4618 }
4619
4620 fn container_create(name: ptr<u8>, mem_limit: u64) -> ptr<AegisContainer> {
4621 for i in 0..64 {
4622 if !global_containers[i].is_active {
4623 global_containers[i].container_id = container_count;
4624 container_count = container_count + 1;
4625 strcpy(&(global_containers[i].name[0]) as ptr<u8>, name);
4626 global_containers[i].memory_limit = mem_limit;
4627 global_containers[i].current_memory = 0;
4628 global_containers[i].pid_offset = container_count * 10000;
4629 global_containers[i].network_isolated = true;
4630
4631 let root_name = pmm_alloc_blocks(1) as ptr<u8>;
4632 strcpy(root_name, "c_root" as ptr<u8>);
4633 global_containers[i].vfs_root = vfs_create_node(global_vfs_root, root_name, 0x07);
4634 pmm_free_blocks(root_name as u64, 1);
4635
4636 global_containers[i].is_active = true;
4637 return &global_containers[i];
4638 }
4639 }
4640 return 0 as ptr<AegisContainer>;
4641 }
4642
4643 fn container_execute(container: ptr<AegisContainer>, path: ptr<u8>) -> u64 {
4644 let node = vfs_find_child((*container).vfs_root, path);
4645 if node == 0 as ptr<VfsNode> { return 0; }
4646
4647 let pid = execve_ring3(path, 0, 0);
4648 if pid != 0 {
4649 let mut proc = process_queue;
4650 while proc != 0 as ptr<ProcessControlBlock> {
4651 if (*proc).pid == pid {
4652 (*proc).pid = (*container).pid_offset + pid;
4653 break;
4654 }
4655 proc = (*proc).next;
4656 }
4657 return (*container).pid_offset + pid;
4658 }
4659 return 0;
4660 }
4661
4662 struct IntelGpuRing {
4663 tail: u32,
4664 head: u32,
4665 start: u32,
4666 ctl: u32,
4667 }
4668
4669 let mut intel_mmio_base: u64 = 0;
4670 let mut intel_ring_buf: ptr<u32>;
4671 let mut intel_ring_tail: u32 = 0;
4672
4673 fn intel_gpu_read(offset: u32) -> u32 {
4674 let ptr = (intel_mmio_base + offset as u64) as ptr<u32>;
4675 return *ptr;
4676 }
4677
4678 fn intel_gpu_write(offset: u32, val: u32) {
4679 let ptr = (intel_mmio_base + offset as u64) as ptr<u32>;
4680 *ptr = val;
4681 }
4682
4683 fn intel_gpu_init(bar0: u64) {
4684 intel_mmio_base = bar0 & 0xFFFFFFFFFFFFFFF0;
4685 intel_ring_buf = pmm_alloc_blocks(4) as ptr<u32>;
4686 memset(intel_ring_buf as ptr<u8>, 0, PAGE_SIZE * 4);
4687
4688 intel_gpu_write(0x02080, 0);
4689 intel_gpu_write(0x02030, 0);
4690 intel_gpu_write(0x02034, intel_ring_buf as u64 as u32);
4691 let ring_size = (PAGE_SIZE * 4) as u32;
4692 intel_gpu_write(0x02038, ((ring_size / 4096) - 1) | 1);
4693
4694 intel_ring_tail = 0;
4695 }
4696
4697 fn intel_gpu_submit_cmd(cmd: u32) {
4698 *(intel_ring_buf as u64 + intel_ring_tail as u64 * 4) as ptr<u32> = cmd;
4699 intel_ring_tail = (intel_ring_tail + 1) % ((PAGE_SIZE as u32 * 4) / 4);
4700 let aligned_tail = (intel_ring_tail * 4) & 0x1FFFF8;
4701 intel_gpu_write(0x02030, aligned_tail);
4702 }
4703
4704 fn intel_gpu_fill_rect(x: u32, y: u32, w: u32, h: u32, color: u32) {
4705 let cmd_len = 6;
4706 intel_gpu_submit_cmd(0x50000000 | (cmd_len - 2));
4707 intel_gpu_submit_cmd((y << 16) | x);
4708 intel_gpu_submit_cmd(((y + h) << 16) | (x + w));
4709 intel_gpu_submit_cmd(color);
4710 intel_gpu_submit_cmd(0);
4711 intel_gpu_submit_cmd(0);
4712 }
4713
4714 const PCI_CAP_ID_MSI: u8 = 0x05;
4715 const PCI_CAP_ID_MSIX: u8 = 0x11;
4716
4717 struct MsixTableEntry {
4718 msg_addr_lo: u32,
4719 msg_addr_hi: u32,
4720 msg_data: u32,
4721 vector_ctrl: u32,
4722 }
4723
4724 fn pcie_find_capability(base: u64, bus: u8, dev: u8, func: u8, cap_id: u8) -> u8 {
4725 let status = pcie_read_16(base, bus, dev, func, 0x06);
4726 if (status & 0x0010) == 0 { return 0; }
4727
4728 let mut cap_ptr = pcie_read_16(base, bus, dev, func, 0x34) & 0xFC;
4729 while cap_ptr != 0 {
4730 let cap_data = pcie_read_16(base, bus, dev, func, cap_ptr);
4731 let id = (cap_data & 0xFF) as u8;
4732 let next = ((cap_data >> 8) & 0xFC) as u8;
4733 if id == cap_id { return cap_ptr as u8; }
4734 cap_ptr = next as u16;
4735 }
4736 return 0;
4737 }
4738
4739 fn pcie_enable_msix(base: u64, bus: u8, dev: u8, func: u8, vector: u8, apic_id: u8) {
4740 let cap_offset = pcie_find_capability(base, bus, dev, func, PCI_CAP_ID_MSIX);
4741 if cap_offset == 0 { return; }
4742
4743 let msg_ctrl = pcie_read_16(base, bus, dev, func, cap_offset as u16 + 2);
4744 let table_offset_reg = pcie_read_32(base, bus, dev, func, cap_offset as u16 + 4);
4745 let bir = (table_offset_reg & 0x07) as u8;
4746 let table_offset = table_offset_reg & 0xFFFFFFF8;
4747
4748 let bar_reg = 0x10 + (bir * 4);
4749 let bar_val = pcie_read_32(base, bus, dev, func, bar_reg as u16);
4750 let bar_base = (bar_val & 0xFFFFFFF0) as u64;
4751
4752 let table_ptr = (bar_base + table_offset as u64) as ptr<MsixTableEntry>;
4753
4754 let addr_lo = 0xFEE00000 | ((apic_id as u32) << 12);
4755 let data = vector as u32;
4756
4757 (*table_ptr).msg_addr_lo = addr_lo;
4758 (*table_ptr).msg_addr_hi = 0;
4759 (*table_ptr).msg_data = data;
4760 (*table_ptr).vector_ctrl = 0;
4761
4762 pcie_write_32(base, bus, dev, func, cap_offset as u16 + 2, (msg_ctrl | 0x8000) as u32);
4763 }
4764
4765 struct RiffHeader {
4766 chunk_id: u32,
4767 chunk_size: u32,
4768 format: u32,
4769 }
4770
4771 struct WavFormatChunk {
4772 subchunk1_id: u32,
4773 subchunk1_size: u32,
4774 audio_format: u16,
4775 num_channels: u16,
4776 sample_rate: u32,
4777 byte_rate: u32,
4778 block_align: u16,
4779 bits_per_sample: u16,
4780 }
4781
4782 struct WavDataChunk {
4783 subchunk2_id: u32,
4784 subchunk2_size: u32,
4785 }
4786
4787 fn audio_play_wav(wav_data: ptr<u8>) {
4788 let riff = wav_data as ptr<RiffHeader>;
4789 if (*riff).chunk_id != 0x46464952 { return; } // 'RIFF'
4790 if (*riff).format != 0x45564157 { return; } // 'WAVE'
4791
4792 let fmt = (wav_data as u64 + sizeof(RiffHeader) as u64) as ptr<WavFormatChunk>;
4793 if (*fmt).subchunk1_id != 0x20746d66 { return; } // 'fmt '
4794
4795 let data_offset = sizeof(RiffHeader) as u64 + 8 + (*fmt).subchunk1_size as u64;
4796 let data_chunk = (wav_data as u64 + data_offset) as ptr<WavDataChunk>;
4797 if (*data_chunk).subchunk2_id != 0x61746164 { return; } // 'data'
4798
4799 let pcm_data = (wav_data as u64 + data_offset + 8) as ptr<u8>;
4800 let pcm_size = (*data_chunk).subchunk2_size;
4801
4802 mixer_play_pcm(pcm_data, pcm_size / 4, (*fmt).sample_rate);
4803 }
4804
4805 struct NatEntry {
4806 internal_ip: Ipv4Addr,
4807 internal_port: u16,
4808 external_port: u16,
4809 protocol: u8,
4810 is_active: bool,
4811 }
4812
4813 let mut global_nat_table: [NatEntry; 1024];
4814 let mut nat_next_port: u16 = 50000;
4815
4816 fn nat_init() {
4817 for i in 0..1024 {
4818 global_nat_table[i].is_active = false;
4819 }
4820 }
4821
4822 fn nat_add_mapping(int_ip: Ipv4Addr, int_port: u16, proto: u8) -> u16 {
4823 for i in 0..1024 {
4824 if !global_nat_table[i].is_active {
4825 global_nat_table[i].internal_ip = int_ip;
4826 global_nat_table[i].internal_port = int_port;
4827 global_nat_table[i].external_port = nat_next_port;
4828 global_nat_table[i].protocol = proto;
4829 global_nat_table[i].is_active = true;
4830
4831 let port = nat_next_port;
4832 nat_next_port = nat_next_port + 1;
4833 if nat_next_port > 65000 { nat_next_port = 50000; }
4834 return port;
4835 }
4836 }
4837 return 0;
4838 }
4839
4840 fn nat_translate_outbound(packet: ptr<u8>) {
4841 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
4842 let proto = (*iph).protocol;
4843
4844 if proto == 6 {
4845 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
4846 let ext_port = nat_add_mapping((*iph).src_ip, htons((*tcph).src_port), proto);
4847
4848 for i in 0..4 { (*iph).src_ip.addr[i] = system_ip.addr[i]; }
4849 (*tcph).src_port = htons(ext_port);
4850 (*tcph).checksum = 0;
4851 (*iph).checksum = 0;
4852 }
4853 }
4854
4855 fn nat_translate_inbound(packet: ptr<u8>) -> bool {
4856 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
4857 let proto = (*iph).protocol;
4858
4859 if proto == 6 {
4860 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
4861 let dest_port = htons((*tcph).dest_port);
4862
4863 for i in 0..1024 {
4864 if global_nat_table[i].is_active && global_nat_table[i].external_port == dest_port && global_nat_table[i].protocol == proto {
4865 for j in 0..4 { (*iph).dest_ip.addr[j] = global_nat_table[i].internal_ip.addr[j]; }
4866 (*tcph).dest_port = htons(global_nat_table[i].internal_port);
4867 return true;
4868 }
4869 }
4870 }
4871 return false;
4872 }
4873
4874 struct AhciCmdFis {
4875 fis_type: u8,
4876 pmport_c: u8,
4877 command: u8,
4878 feature_l: u8,
4879 lba0: u8,
4880 lba1: u8,
4881 lba2: u8,
4882 device: u8,
4883 lba3: u8,
4884 lba4: u8,
4885 lba5: u8,
4886 feature_h: u8,
4887 count_l: u8,
4888 count_h: u8,
4889 icc: u8,
4890 control: u8,
4891 rsv1: [u8; 4],
4892 }
4893
4894 fn ahci_find_cmd_slot(port: ptr<AHCIPortRegs>) -> i32 {
4895 let slots = ((*global_ahci_hba).cap >> 8) & 0x1F;
4896 for i in 0..=slots {
4897 if ((*port).ci & (1 << i)) == 0 && ((*port).sact & (1 << i)) == 0 {
4898 return i as i32;
4899 }
4900 }
4901 return -1;
4902 }
4903
4904 fn ahci_read_sectors(port: ptr<AHCIPortRegs>, start_lba: u64, count: u32, buf_phys: u64) -> bool {
4905 (*port).is = 0xFFFFFFFF;
4906 let slot = ahci_find_cmd_slot(port);
4907 if slot == -1 { return false; }
4908
4909 let cmd_header = ((*port).clb + (slot as u64 * sizeof(AHCICmdHeader) as u64)) as ptr<AHCICmdHeader>;
4910 (*cmd_header).cfl_p_r_c = (sizeof(AhciCmdFis) / 4) as u16;
4911 (*cmd_header).prdtl = 1;
4912
4913 let cmd_table = (*cmd_header).ctba as ptr<AHCICmdTable>;
4914 memset(cmd_table as ptr<u8>, 0, sizeof(AHCICmdTable) as u64);
4915
4916 (*cmd_table).prdt_entry[0].dba = buf_phys;
4917 (*cmd_table).prdt_entry[0].dbc_i = (count * 512) - 1;
4918
4919 let fis = &(*cmd_table).cfis[0] as ptr<AhciCmdFis>;
4920 (*fis).fis_type = 0x27;
4921 (*fis).pmport_c = 0x80;
4922 (*fis).command = 0x25;
4923
4924 (*fis).lba0 = (start_lba & 0xFF) as u8;
4925 (*fis).lba1 = ((start_lba >> 8) & 0xFF) as u8;
4926 (*fis).lba2 = ((start_lba >> 16) & 0xFF) as u8;
4927 (*fis).device = 0x40;
4928
4929 (*fis).lba3 = ((start_lba >> 24) & 0xFF) as u8;
4930 (*fis).lba4 = ((start_lba >> 32) & 0xFF) as u8;
4931 (*fis).lba5 = ((start_lba >> 40) & 0xFF) as u8;
4932
4933 (*fis).count_l = (count & 0xFF) as u8;
4934 (*fis).count_h = ((count >> 8) & 0xFF) as u8;
4935
4936 while ((*port).tfd & (0x80 | 0x08)) != 0 { cpu_pause(); }
4937 (*port).ci = 1 << slot;
4938
4939 while true {
4940 if ((*port).ci & (1 << slot)) == 0 { break; }
4941 if ((*port).is & 0x40000000) != 0 { return false; }
4942 cpu_pause();
4943 }
4944 return true;
4945 }
4946
4947 fn ahci_write_sectors(port: ptr<AHCIPortRegs>, start_lba: u64, count: u32, buf_phys: u64) -> bool {
4948 (*port).is = 0xFFFFFFFF;
4949 let slot = ahci_find_cmd_slot(port);
4950 if slot == -1 { return false; }
4951
4952 let cmd_header = ((*port).clb + (slot as u64 * sizeof(AHCICmdHeader) as u64)) as ptr<AHCICmdHeader>;
4953 (*cmd_header).cfl_p_r_c = ((sizeof(AhciCmdFis) / 4) as u16) | 0x0040;
4954 (*cmd_header).prdtl = 1;
4955
4956 let cmd_table = (*cmd_header).ctba as ptr<AHCICmdTable>;
4957 memset(cmd_table as ptr<u8>, 0, sizeof(AHCICmdTable) as u64);
4958
4959 (*cmd_table).prdt_entry[0].dba = buf_phys;
4960 (*cmd_table).prdt_entry[0].dbc_i = (count * 512) - 1;
4961
4962 let fis = &(*cmd_table).cfis[0] as ptr<AhciCmdFis>;
4963 (*fis).fis_type = 0x27;
4964 (*fis).pmport_c = 0x80;
4965 (*fis).command = 0x35;
4966
4967 (*fis).lba0 = (start_lba & 0xFF) as u8;
4968 (*fis).lba1 = ((start_lba >> 8) & 0xFF) as u8;
4969 (*fis).lba2 = ((start_lba >> 16) & 0xFF) as u8;
4970 (*fis).device = 0x40;
4971
4972 (*fis).lba3 = ((start_lba >> 24) & 0xFF) as u8;
4973 (*fis).lba4 = ((start_lba >> 32) & 0xFF) as u8;
4974 (*fis).lba5 = ((start_lba >> 40) & 0xFF) as u8;
4975
4976 (*fis).count_l = (count & 0xFF) as u8;
4977 (*fis).count_h = ((count >> 8) & 0xFF) as u8;
4978
4979 while ((*port).tfd & (0x80 | 0x08)) != 0 { cpu_pause(); }
4980 (*port).ci = 1 << slot;
4981
4982 while true {
4983 if ((*port).ci & (1 << slot)) == 0 { break; }
4984 if ((*port).is & 0x40000000) != 0 { return false; }
4985 cpu_pause();
4986 }
4987 return true;
4988 }
4989
4990 struct SignalContext {
4991 pending_mask: u32,
4992 blocked_mask: u32,
4993 handlers: [u64; 32],
4994 trampoline_addr: u64,
4995 saved_ctx: CpuContext,
4996 is_handling: bool,
4997 }
4998
4999 struct ProcessControlBlockExt {
5000 base: ProcessControlBlock,
5001 sig_ctx: ptr<SignalContext>,
5002 }
5003
5004 const SIGKILL: u32 = 9;
5005 const SIGSEGV: u32 = 11;
5006 const SIGTERM: u32 = 15;
5007
5008 fn signal_init_process(proc: ptr<ProcessControlBlock>) {
5009 let proc_ext = proc as ptr<ProcessControlBlockExt>;
5010 (*proc_ext).sig_ctx = pmm_alloc_blocks(1) as ptr<SignalContext>;
5011 memset((*proc_ext).sig_ctx as ptr<u8>, 0, sizeof(SignalContext) as u64);
5012 }
5013
5014 fn signal_send(target_pid: u64, signum: u32) -> bool {
5015 let mut curr = process_queue;
5016 while curr != 0 as ptr<ProcessControlBlock> {
5017 if (*curr).pid == target_pid {
5018 let proc_ext = curr as ptr<ProcessControlBlockExt>;
5019 if (*(*proc_ext).sig_ctx).is_handling { return false; }
5020 (*(*proc_ext).sig_ctx).pending_mask |= 1 << signum;
5021 if signum == SIGKILL {
5022 (*curr).state = 0;
5023 }
5024 return true;
5025 }
5026 curr = (*curr).next;
5027 }
5028 return false;
5029 }
5030
5031 fn signal_check_pending() {
5032 if current_process == 0 as ptr<ProcessControlBlock> { return; }
5033 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
5034 let sig_ctx = (*proc_ext).sig_ctx;
5035
5036 if (*sig_ctx).is_handling { return; }
5037
5038 let active_sigs = (*sig_ctx).pending_mask & !(*sig_ctx).blocked_mask;
5039 if active_sigs == 0 { return; }
5040
5041 for i in 1..32 {
5042 if (active_sigs & (1 << i)) != 0 {
5043 (*sig_ctx).pending_mask &= !(1 << i);
5044 let handler = (*sig_ctx).handlers[i as usize];
5045 if handler != 0 {
5046 memcpy(&((*sig_ctx).saved_ctx) as ptr<u8>, (*current_process).context as ptr<u8>, sizeof(CpuContext) as u64);
5047 (*sig_ctx).is_handling = true;
5048 (*(*current_process).context).rip = handler;
5049 (*(*current_process).context).rdi = i as u64;
5050 let rsp = (*(*current_process).context).rsp;
5051 (*(*current_process).context).rsp = rsp - 128;
5052 return;
5053 }
5054 }
5055 }
5056 }
5057
5058 fn signal_return() {
5059 if current_process == 0 as ptr<ProcessControlBlock> { return; }
5060 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
5061 let sig_ctx = (*proc_ext).sig_ctx;
5062 if !(*sig_ctx).is_handling { return; }
5063
5064 memcpy((*current_process).context as ptr<u8>, &((*sig_ctx).saved_ctx) as ptr<u8>, sizeof(CpuContext) as u64);
5065 (*sig_ctx).is_handling = false;
5066 }
5067
5068 struct TcpCongestionExt {
5069 cwnd: u32,
5070 ssthresh: u32,
5071 dup_acks: u32,
5072 rtt: u32,
5073 rto: u32,
5074 in_fast_recovery: bool,
5075 }
5076
5077 let mut global_tcp_cc: [TcpCongestionExt; 1024];
5078
5079 fn tcp_cc_init(sock_idx: u32) {
5080 global_tcp_cc[sock_idx as usize].cwnd = 1460;
5081 global_tcp_cc[sock_idx as usize].ssthresh = 65535;
5082 global_tcp_cc[sock_idx as usize].dup_acks = 0;
5083 global_tcp_cc[sock_idx as usize].rto = 1000;
5084 global_tcp_cc[sock_idx as usize].in_fast_recovery = false;
5085 }
5086
5087 fn tcp_cc_ack_received(sock_idx: u32, ack_diff: u32, is_dup: bool) {
5088 let cc = &global_tcp_cc[sock_idx as usize];
5089 if is_dup {
5090 (*cc).dup_acks = (*cc).dup_acks + 1;
5091 if (*cc).dup_acks == 3 {
5092 (*cc).ssthresh = (*cc).cwnd / 2;
5093 if (*cc).ssthresh < 1460 * 2 { (*cc).ssthresh = 1460 * 2; }
5094 (*cc).cwnd = (*cc).ssthresh + 3 * 1460;
5095 (*cc).in_fast_recovery = true;
5096 } else if (*cc).in_fast_recovery {
5097 (*cc).cwnd = (*cc).cwnd + 1460;
5098 }
5099 } else {
5100 (*cc).dup_acks = 0;
5101 if (*cc).in_fast_recovery {
5102 (*cc).cwnd = (*cc).ssthresh;
5103 (*cc).in_fast_recovery = false;
5104 } else {
5105 if (*cc).cwnd < (*cc).ssthresh {
5106 (*cc).cwnd = (*cc).cwnd + 1460;
5107 } else {
5108 (*cc).cwnd = (*cc).cwnd + (1460 * 1460) / (*cc).cwnd;
5109 }
5110 }
5111 }
5112 }
5113
5114 fn tcp_cc_timeout(sock_idx: u32) {
5115 let cc = &global_tcp_cc[sock_idx as usize];
5116 (*cc).ssthresh = (*cc).cwnd / 2;
5117 if (*cc).ssthresh < 1460 * 2 { (*cc).ssthresh = 1460 * 2; }
5118 (*cc).cwnd = 1460;
5119 (*cc).dup_acks = 0;
5120 (*cc).in_fast_recovery = false;
5121 (*cc).rto = (*cc).rto * 2;
5122 if (*cc).rto > 64000 { (*cc).rto = 64000; }
5123 }
5124
5125 struct VirtualConsole {
5126 id: u32,
5127 buffer_phys: u64,
5128 cursor_x: u32,
5129 cursor_y: u32,
5130 fg_color: u32,
5131 bg_color: u32,
5132 is_active: bool,
5133 }
5134
5135 let mut global_vt_list: [VirtualConsole; 6];
5136 let mut vt_active_id: u32 = 0;
5137 let mut vt_lock: Spinlock;
5138
5139 fn vt_init() {
5140 spin_init(&vt_lock);
5141 for i in 0..6 {
5142 global_vt_list[i].id = i as u32;
5143 global_vt_list[i].buffer_phys = pmm_alloc_blocks((comp_width * comp_height * 4) / PAGE_SIZE as u32 + 1);
5144 memset(global_vt_list[i].buffer_phys as ptr<u8>, 0, (comp_width * comp_height * 4) as u64);
5145 global_vt_list[i].cursor_x = 0;
5146 global_vt_list[i].cursor_y = 0;
5147 global_vt_list[i].fg_color = 0xFFFFFF;
5148 global_vt_list[i].bg_color = 0x000000;
5149 global_vt_list[i].is_active = false;
5150 }
5151 global_vt_list[0].is_active = true;
5152 }
5153
5154 fn vt_switch(new_id: u32) {
5155 if new_id >= 6 || new_id == vt_active_id { return; }
5156 spin_lock(&vt_lock);
5157 global_vt_list[vt_active_id as usize].is_active = false;
5158 vt_active_id = new_id;
5159 global_vt_list[vt_active_id as usize].is_active = true;
5160 memcpy(fb_ptr as ptr<u8>, global_vt_list[vt_active_id as usize].buffer_phys as ptr<u8>, (comp_width * comp_height * 4) as u64);
5161 spin_unlock(&vt_lock);
5162 }
5163
5164 fn vt_write_char(vt_id: u32, c: u8) {
5165 let vt = &global_vt_list[vt_id as usize];
5166 if c == 10 {
5167 (*vt).cursor_x = 0;
5168 (*vt).cursor_y = (*vt).cursor_y + system_font_h;
5169 } else {
5170 let buf = (*vt).buffer_phys as ptr<u32>;
5171 let glyph_offset = c as u64 * system_font_h as u64;
5172 let glyph = (system_font_ptr as u64 + glyph_offset) as ptr<u8>;
5173
5174 for cy in 0..system_font_h {
5175 let row = *(glyph + cy as u64);
5176 for cx in 0..system_font_w {
5177 let px = (*vt).cursor_x + cx;
5178 let py = (*vt).cursor_y + cy;
5179 if px < comp_width && py < comp_height {
5180 let p_idx = (py * comp_width + px) as u64;
5181 if (row & (0x80 >> cx)) != 0 {
5182 *(buf + p_idx) = (*vt).fg_color;
5183 } else {
5184 *(buf + p_idx) = (*vt).bg_color;
5185 }
5186 }
5187 }
5188 }
5189 (*vt).cursor_x = (*vt).cursor_x + system_font_w;
5190 if (*vt).cursor_x >= comp_width {
5191 (*vt).cursor_x = 0;
5192 (*vt).cursor_y = (*vt).cursor_y + system_font_h;
5193 }
5194 }
5195
5196 if (*vt).cursor_y >= comp_height {
5197 let buf = (*vt).buffer_phys as ptr<u32>;
5198 let row_bytes = (comp_width * system_font_h * 4) as u64;
5199 let total_bytes = (comp_width * comp_height * 4) as u64;
5200 memmove(buf as ptr<u8>, (buf as u64 + row_bytes) as ptr<u8>, total_bytes - row_bytes);
5201 memset((buf as u64 + total_bytes - row_bytes) as ptr<u8>, 0, row_bytes);
5202 (*vt).cursor_y = (*vt).cursor_y - system_font_h;
5203 }
5204
5205 if (*vt).is_active {
5206 memcpy(fb_ptr as ptr<u8>, (*vt).buffer_phys as ptr<u8>, (comp_width * comp_height * 4) as u64);
5207 }
5208 }
5209
5210 struct AmlNode {
5211 opcode: u8,
5212 name: [u8; 4],
5213 length: u32,
5214 data_ptr: ptr<u8>,
5215 parent: ptr<AmlNode>,
5216 child: ptr<AmlNode>,
5217 next: ptr<AmlNode>,
5218 }
5219
5220 let mut aml_root: ptr<AmlNode>;
5221
5222 fn aml_parse_name(data: ptr<u8>) -> u32 {
5223 let mut offset: u32 = 0;
5224 if *data == 0x5C { offset = offset + 1; }
5225 if *(data as u64 + offset as u64) as ptr<u8> == 0x2E { offset = offset + 1; }
5226 offset = offset + 4;
5227 return offset;
5228 }
5229
5230 fn aml_parse_pkg_length(data: ptr<u8>) -> (u32, u32) {
5231 let lead = *data;
5232 let byte_count = (lead >> 6) as u32;
5233 if byte_count == 0 {
5234 return ((lead & 0x3F) as u32, 1);
5235 }
5236 let mut length = (lead & 0x0F) as u32;
5237 for i in 0..byte_count {
5238 length |= (*(data as u64 + 1 + i as u64) as u32) << (4 + i * 8);
5239 }
5240 return (length, byte_count + 1);
5241 }
5242
5243 fn aml_process_scope(parent: ptr<AmlNode>, data: ptr<u8>, limit: u32) {
5244 let mut offset: u32 = 0;
5245 while offset < limit {
5246 let opcode = *(data as u64 + offset as u64) as ptr<u8>;
5247 let mut parsed_len: u32 = 1;
5248
5249 if opcode == 0x10 {
5250 let (pkg_len, pkg_bytes) = aml_parse_pkg_length((data as u64 + offset as u64 + 1) as ptr<u8>);
5251 let name_offset = aml_parse_name((data as u64 + offset as u64 + 1 + pkg_bytes as u64) as ptr<u8>);
5252 parsed_len = 1 + pkg_bytes + pkg_len;
5253
5254 let node = pmm_alloc_blocks(1) as ptr<AmlNode>;
5255 memset(node as ptr<u8>, 0, sizeof(AmlNode) as u64);
5256 (*node).opcode = opcode;
5257 (*node).parent = parent;
5258
5259 if (*parent).child == 0 as ptr<AmlNode> {
5260 (*parent).child = node;
5261 } else {
5262 let mut curr = (*parent).child;
5263 while (*curr).next != 0 as ptr<AmlNode> { curr = (*curr).next; }
5264 (*curr).next = node;
5265 }
5266
5267 aml_process_scope(node, (data as u64 + offset as u64 + 1 + pkg_bytes as u64 + name_offset as u64) as ptr<u8>, pkg_len - name_offset);
5268 } else if opcode == 0x14 {
5269 let (pkg_len, pkg_bytes) = aml_parse_pkg_length((data as u64 + offset as u64 + 1) as ptr<u8>);
5270 parsed_len = 1 + pkg_bytes + pkg_len;
5271 } else if opcode == 0x08 {
5272 let name_offset = aml_parse_name((data as u64 + offset as u64 + 1) as ptr<u8>);
5273 parsed_len = 1 + name_offset + 1;
5274 } else {
5275 parsed_len = 1;
5276 }
5277 offset = offset + parsed_len;
5278 }
5279 }
5280
5281 fn acpi_dsdt_init() {
5282 if acpi_fadt == 0 as ptr<FADTHeader> { return; }
5283 let dsdt_ptr = (*acpi_fadt).dsdt as u64 as ptr<ACPISDTHeader>;
5284 if !acpi_checksum(dsdt_ptr as ptr<u8>, (*dsdt_ptr).length) { return; }
5285
5286 aml_root = pmm_alloc_blocks(1) as ptr<AmlNode>;
5287 memset(aml_root as ptr<u8>, 0, sizeof(AmlNode) as u64);
5288
5289 let aml_data = (dsdt_ptr as u64 + sizeof(ACPISDTHeader) as u64) as ptr<u8>;
5290 let aml_len = (*dsdt_ptr).length - sizeof(ACPISDTHeader) as u32;
5291 aml_process_scope(aml_root, aml_data, aml_len);
5292 }
5293
5294 const DOM_NODE_ELEMENT: u8 = 1;
5295 const DOM_NODE_TEXT: u8 = 2;
5296
5297 struct HtmlAttribute {
5298 name: [u8; 32],
5299 value: [u8; 128],
5300 next: ptr<HtmlAttribute>,
5301 }
5302
5303 struct DomNode {
5304 node_type: u8,
5305 tag_name: [u8; 32],
5306 text_content: ptr<u8>,
5307 attributes: ptr<HtmlAttribute>,
5308 parent: ptr<DomNode>,
5309 first_child: ptr<DomNode>,
5310 next_sibling: ptr<DomNode>,
5311 }
5312
5313 let mut dom_node_pool: ptr<DomNode>;
5314 let mut dom_pool_idx: u32 = 0;
5315
5316 fn html_init_parser() {
5317 dom_node_pool = pmm_alloc_blocks(64) as ptr<DomNode>;
5318 memset(dom_node_pool as ptr<u8>, 0, PAGE_SIZE * 64);
5319 dom_pool_idx = 0;
5320 }
5321
5322 fn html_alloc_node() -> ptr<DomNode> {
5323 let node = (dom_node_pool as u64 + dom_pool_idx as u64 * sizeof(DomNode) as u64) as ptr<DomNode>;
5324 dom_pool_idx = dom_pool_idx + 1;
5325 return node;
5326 }
5327
5328 fn html_skip_whitespace(html: ptr<u8>, pos: ptr<u32>) {
5329 while *(html as u64 + *pos as u64) as ptr<u8> == ' ' as u8 ||
5330 *(html as u64 + *pos as u64) as ptr<u8> == 10 ||
5331 *(html as u64 + *pos as u64) as ptr<u8> == 9 ||
5332 *(html as u64 + *pos as u64) as ptr<u8> == 13 {
5333 *pos = *pos + 1;
5334 }
5335 }
5336
5337 fn html_parse_tag_name(html: ptr<u8>, pos: ptr<u32>, out_name: ptr<u8>) {
5338 let mut i: u32 = 0;
5339 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 &&
5340 *(html as u64 + *pos as u64) as ptr<u8> != ' ' as u8 &&
5341 *(html as u64 + *pos as u64) as ptr<u8> != '/' as u8 &&
5342 *(html as u64 + *pos as u64) as ptr<u8> != 0 &&
5343 i < 31 {
5344 *(out_name as u64 + i as u64) as ptr<u8> = *(html as u64 + *pos as u64) as ptr<u8>;
5345 *pos = *pos + 1;
5346 i = i + 1;
5347 }
5348 *(out_name as u64 + i as u64) as ptr<u8> = 0;
5349 }
5350
5351 fn html_parse_node(html: ptr<u8>, pos: ptr<u32>, parent: ptr<DomNode>) -> ptr<DomNode> {
5352 html_skip_whitespace(html, pos);
5353 if *(html as u64 + *pos as u64) as ptr<u8> == 0 { return 0 as ptr<DomNode>; }
5354
5355 let node = html_alloc_node();
5356 (*node).parent = parent;
5357
5358 if *(html as u64 + *pos as u64) as ptr<u8> == '<' as u8 {
5359 *pos = *pos + 1;
5360 if *(html as u64 + *pos as u64) as ptr<u8> == '/' as u8 {
5361 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
5362 *pos = *pos + 1;
5363 }
5364 if *(html as u64 + *pos as u64) as ptr<u8> == '>' as u8 { *pos = *pos + 1; }
5365 return 0 as ptr<DomNode>;
5366 }
5367
5368 (*node).node_type = DOM_NODE_ELEMENT;
5369 html_parse_tag_name(html, pos, &((*node).tag_name[0]) as ptr<u8>);
5370
5371 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
5372 *pos = *pos + 1;
5373 }
5374
5375 let mut is_self_closing = false;
5376 if *(html as u64 + *pos as u64 - 1) as ptr<u8> == '/' as u8 {
5377 is_self_closing = true;
5378 }
5379
5380 if *(html as u64 + *pos as u64) as ptr<u8> == '>' as u8 { *pos = *pos + 1; }
5381
5382 if !is_self_closing {
5383 let mut last_child = 0 as ptr<DomNode>;
5384 loop {
5385 let child = html_parse_node(html, pos, node);
5386 if child == 0 as ptr<DomNode> { break; }
5387 if (*node).first_child == 0 as ptr<DomNode> {
5388 (*node).first_child = child;
5389 } else {
5390 (*last_child).next_sibling = child;
5391 }
5392 last_child = child;
5393 }
5394 }
5395 } else {
5396 (*node).node_type = DOM_NODE_TEXT;
5397 let mut start_pos = *pos;
5398 let mut len: u32 = 0;
5399 while *(html as u64 + *pos as u64) as ptr<u8> != '<' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
5400 *pos = *pos + 1;
5401 len = len + 1;
5402 }
5403 (*node).text_content = pmm_alloc_blocks((len / PAGE_SIZE as u32) + 1) as ptr<u8>;
5404 memcpy((*node).text_content, (html as u64 + start_pos as u64) as ptr<u8>, len as u64);
5405 *((*node).text_content as u64 + len as u64) as ptr<u8> = 0;
5406 }
5407
5408 return node;
5409 }
5410
5411 const RAID_LEVEL_5: u32 = 5;
5412 const RAID_STRIPE_SIZE: u64 = 65536;
5413
5414 struct RaidDisk {
5415 disk_id: u32,
5416 ahci_port: ptr<AHCIPortRegs>,
5417 is_online: bool,
5418 total_sectors: u64,
5419 }
5420
5421 struct RaidArray {
5422 array_id: u32,
5423 level: u32,
5424 disks: [RaidDisk; 8],
5425 disk_count: u32,
5426 online_count: u32,
5427 total_capacity: u64,
5428 stripe_size: u64,
5429 }
5430
5431 let mut global_raid_sys: RaidArray;
5432
5433 fn raid_init_system() {
5434 global_raid_sys.array_id = 1;
5435 global_raid_sys.level = RAID_LEVEL_5;
5436 global_raid_sys.disk_count = 0;
5437 global_raid_sys.online_count = 0;
5438 global_raid_sys.stripe_size = RAID_STRIPE_SIZE;
5439 }
5440
5441 fn raid_add_disk(port: ptr<AHCIPortRegs>, sectors: u64) {
5442 if global_raid_sys.disk_count < 8 {
5443 let idx = global_raid_sys.disk_count;
5444 global_raid_sys.disks[idx as usize].disk_id = idx;
5445 global_raid_sys.disks[idx as usize].ahci_port = port;
5446 global_raid_sys.disks[idx as usize].is_online = true;
5447 global_raid_sys.disks[idx as usize].total_sectors = sectors;
5448 global_raid_sys.disk_count = global_raid_sys.disk_count + 1;
5449 global_raid_sys.online_count = global_raid_sys.online_count + 1;
5450 global_raid_sys.total_capacity = (global_raid_sys.disk_count - 1) as u64 * sectors * 512;
5451 }
5452 }
5453
5454 fn raid_compute_parity(buffers: ptr<u64>, count: u32, parity_buf: u64, size: u64) {
5455 let p_ptr = parity_buf as ptr<u64>;
5456 for i in 0..(size / 8) {
5457 let mut xor_val: u64 = 0;
5458 for d in 0..count {
5459 let buf_ptr = *(buffers + d as u64) as ptr<u64>;
5460 xor_val = xor_val ^ *(buf_ptr as u64 + i as u64 * 8) as ptr<u64>;
5461 }
5462 *(p_ptr as u64 + i as u64 * 8) as ptr<u64> = xor_val;
5463 }
5464 }
5465
5466 fn raid_reconstruct_data(buffers: ptr<u64>, count: u32, parity_buf: u64, missing_idx: u32, size: u64) {
5467 let missing_ptr = *(buffers + missing_idx as u64) as ptr<u64>;
5468 let p_ptr = parity_buf as ptr<u64>;
5469 for i in 0..(size / 8) {
5470 let mut xor_val: u64 = *(p_ptr as u64 + i as u64 * 8) as ptr<u64>;
5471 for d in 0..count {
5472 if d != missing_idx {
5473 let buf_ptr = *(buffers + d as u64) as ptr<u64>;
5474 xor_val = xor_val ^ *(buf_ptr as u64 + i as u64 * 8) as ptr<u64>;
5475 }
5476 }
5477 *(missing_ptr as u64 + i as u64 * 8) as ptr<u64> = xor_val;
5478 }
5479 }
5480
5481 fn raid_write_stripe(stripe_lba: u64, data_buffers: ptr<u64>) {
5482 let disk_cnt = global_raid_sys.disk_count;
5483 let parity_disk = (stripe_lba / (RAID_STRIPE_SIZE / 512)) % disk_cnt as u64;
5484
5485 let parity_buf = pmm_alloc_blocks(RAID_STRIPE_SIZE / PAGE_SIZE);
5486 raid_compute_parity(data_buffers, disk_cnt - 1, parity_buf, RAID_STRIPE_SIZE);
5487
5488 let mut data_idx = 0;
5489 for i in 0..disk_cnt {
5490 let port = global_raid_sys.disks[i as usize].ahci_port;
5491 if i as u64 == parity_disk {
5492 ahci_write_sectors(port, stripe_lba, (RAID_STRIPE_SIZE / 512) as u32, parity_buf);
5493 } else {
5494 let d_buf = *(data_buffers + data_idx as u64);
5495 ahci_write_sectors(port, stripe_lba, (RAID_STRIPE_SIZE / 512) as u32, d_buf);
5496 data_idx = data_idx + 1;
5497 }
5498 }
5499 pmm_free_blocks(parity_buf, RAID_STRIPE_SIZE / PAGE_SIZE);
5500 }
5501
5502 struct CpuRunQueue {
5503 core_id: u32,
5504 head: ptr<ProcessControlBlock>,
5505 tail: ptr<ProcessControlBlock>,
5506 load_factor: u32,
5507 lock: Spinlock,
5508 }
5509
5510 let mut global_run_queues: [CpuRunQueue; 256];
5511
5512 fn smp_balancer_init() {
5513 for i in 0..smp_core_count {
5514 global_run_queues[i as usize].core_id = smp_cores[i as usize].apic_id as u32;
5515 global_run_queues[i as usize].head = 0 as ptr<ProcessControlBlock>;
5516 global_run_queues[i as usize].tail = 0 as ptr<ProcessControlBlock>;
5517 global_run_queues[i as usize].load_factor = 0;
5518 spin_init(&(global_run_queues[i as usize].lock));
5519 }
5520 }
5521
5522 fn smp_enqueue_task(core_idx: u32, task: ptr<ProcessControlBlock>) {
5523 let rq = &global_run_queues[core_idx as usize];
5524 spin_lock(&((*rq).lock));
5525 (*task).next = 0 as ptr<ProcessControlBlock>;
5526 if (*rq).tail == 0 as ptr<ProcessControlBlock> {
5527 (*rq).head = task;
5528 (*rq).tail = task;
5529 } else {
5530 (*((*rq).tail)).next = task;
5531 (*rq).tail = task;
5532 }
5533 (*rq).load_factor = (*rq).load_factor + 1;
5534 spin_unlock(&((*rq).lock));
5535 }
5536
5537 fn smp_dequeue_task(core_idx: u32) -> ptr<ProcessControlBlock> {
5538 let rq = &global_run_queues[core_idx as usize];
5539 spin_lock(&((*rq).lock));
5540 if (*rq).head == 0 as ptr<ProcessControlBlock> {
5541 spin_unlock(&((*rq).lock));
5542 return 0 as ptr<ProcessControlBlock>;
5543 }
5544 let task = (*rq).head;
5545 (*rq).head = (*task).next;
5546 if (*rq).head == 0 as ptr<ProcessControlBlock> {
5547 (*rq).tail = 0 as ptr<ProcessControlBlock>;
5548 }
5549 (*rq).load_factor = (*rq).load_factor - 1;
5550 spin_unlock(&((*rq).lock));
5551 return task;
5552 }
5553
5554 fn smp_balance_load() {
5555 let mut max_load: u32 = 0;
5556 let mut min_load: u32 = 0xFFFFFFFF;
5557 let mut busiest_core: u32 = 0;
5558 let mut idlest_core: u32 = 0;
5559
5560 for i in 0..smp_core_count {
5561 let load = global_run_queues[i as usize].load_factor;
5562 if load > max_load { max_load = load; busiest_core = i; }
5563 if load < min_load { min_load = load; idlest_core = i; }
5564 }
5565
5566 if max_load > min_load + 2 {
5567 let task = smp_dequeue_task(busiest_core);
5568 if task != 0 as ptr<ProcessControlBlock> {
5569 smp_enqueue_task(idlest_core, task);
5570 }
5571 }
5572 }
5573
5574 struct WaylandBuffer {
5575 shm_id: u64,
5576 width: u32,
5577 height: u32,
5578 stride: u32,
5579 format: u32,
5580 }
5581
5582 struct WaylandSurface {
5583 surface_id: u32,
5584 owner_pid: u64,
5585 buffer: ptr<WaylandBuffer>,
5586 x: i32,
5587 y: i32,
5588 z_order: u32,
5589 is_mapped: bool,
5590 next: ptr<WaylandSurface>,
5591 }
5592
5593 let mut display_srv_surfaces: ptr<WaylandSurface>;
5594 let mut display_srv_next_id: u32 = 1000;
5595
5596 fn display_srv_create_surface(pid: u64) -> u32 {
5597 let surf = pmm_alloc_blocks(1) as ptr<WaylandSurface>;
5598 memset(surf as ptr<u8>, 0, sizeof(WaylandSurface) as u64);
5599 (*surf).surface_id = display_srv_next_id;
5600 display_srv_next_id = display_srv_next_id + 1;
5601 (*surf).owner_pid = pid;
5602 (*surf).is_mapped = false;
5603 (*surf).next = display_srv_surfaces;
5604 display_srv_surfaces = surf;
5605 return (*surf).surface_id;
5606 }
5607
5608 fn display_srv_attach_buffer(surface_id: u32, shm_id: u64, w: u32, h: u32) {
5609 let mut curr = display_srv_surfaces;
5610 while curr != 0 as ptr<WaylandSurface> {
5611 if (*curr).surface_id == surface_id {
5612 let buf = pmm_alloc_blocks(1) as ptr<WaylandBuffer>;
5613 (*buf).shm_id = shm_id;
5614 (*buf).width = w;
5615 (*buf).height = h;
5616 (*buf).stride = w * 4;
5617 (*buf).format = 1;
5618 (*curr).buffer = buf;
5619 return;
5620 }
5621 curr = (*curr).next;
5622 }
5623 }
5624
5625 fn display_srv_commit(surface_id: u32, x: i32, y: i32) {
5626 let mut curr = display_srv_surfaces;
5627 while curr != 0 as ptr<WaylandSurface> {
5628 if (*curr).surface_id == surface_id {
5629 (*curr).x = x;
5630 (*curr).y = y;
5631 (*curr).is_mapped = true;
5632 return;
5633 }
5634 curr = (*curr).next;
5635 }
5636 }
5637
5638 fn display_srv_composite() {
5639 let bg_color = 0x1A1A1A;
5640 comp_draw_rect(comp_root_window, 0, 0, comp_width, comp_height, bg_color);
5641
5642 let mut curr = display_srv_surfaces;
5643 while curr != 0 as ptr<WaylandSurface> {
5644 if (*curr).is_mapped && (*curr).buffer != 0 as ptr<WaylandBuffer> {
5645 let buf_info = (*curr).buffer;
5646 let mut phys_base: u64 = 0;
5647 for i in 0..256 {
5648 if global_shm_table[i].shm_id == (*buf_info).shm_id {
5649 phys_base = global_shm_table[i].phys_base;
5650 break;
5651 }
5652 }
5653 if phys_base != 0 {
5654 let p_pixels = phys_base as ptr<u32>;
5655 for h in 0..(*buf_info).height {
5656 for w in 0..(*buf_info).width {
5657 let sx = (*curr).x + w as i32;
5658 let sy = (*curr).y + h as i32;
5659 if sx >= 0 && sx < comp_width as i32 && sy >= 0 && sy < comp_height as i32 {
5660 let color = *(p_pixels as u64 + (h * (*buf_info).width + w) as u64 * 4) as ptr<u32>;
5661 if (*color & 0xFF000000) != 0 {
5662 *(comp_back_buffer as u64 + (sy as u32 * comp_width + sx as u32) as u64 * 4) as ptr<u32> = *color;
5663 }
5664 }
5665 }
5666 }
5667 }
5668 }
5669 curr = (*curr).next;
5670 }
5671 memcpy(fb_ptr as ptr<u8>, comp_back_buffer as ptr<u8>, (comp_width * comp_height * 4) as u64);
5672 }
5673
5674 struct XhciIsochTrb {
5675 data_buffer_ptr: u64,
5676 tlc_tdpc_int_cc: u32,
5677 flags: u32,
5678 }
5679
5680 fn xhci_queue_isoch_transfer(ring: ptr<u8>, phys_buf: u64, length: u32, frame_id: u32) {
5681 let trb = ring as ptr<XhciIsochTrb>;
5682 (*trb).data_buffer_ptr = phys_buf;
5683 (*trb).tlc_tdpc_int_cc = length & 0x1FFFF;
5684 (*trb).flags = (frame_id << 20) | (32 << 10) | 1;
5685 }
5686
5687 fn math_exp(x: f32) -> f32 {
5688 let mut sum: f32 = 1.0;
5689 let mut term: f32 = 1.0;
5690 for i in 1..20 {
5691 term = term * x / (i as f32);
5692 sum = sum + term;
5693 }
5694 return sum;
5695 }
5696
5697 struct Tensor2D {
5698 rows: u32,
5699 cols: u32,
5700 data: ptr<f32>,
5701 }
5702
5703 fn tensor_create(rows: u32, cols: u32) -> ptr<Tensor2D> {
5704 let t = pmm_alloc_blocks(1) as ptr<Tensor2D>;
5705 (*t).rows = rows;
5706 (*t).cols = cols;
5707 let bytes = rows * cols * 4;
5708 let pages = (bytes / PAGE_SIZE as u32) + 1;
5709 (*t).data = pmm_alloc_blocks(pages as u64) as ptr<f32>;
5710 memset((*t).data as ptr<u8>, 0, (pages * PAGE_SIZE as u32) as u64);
5711 return t;
5712 }
5713
5714 fn tensor_destroy(t: ptr<Tensor2D>) {
5715 let bytes = (*t).rows * (*t).cols * 4;
5716 let pages = (bytes / PAGE_SIZE as u32) + 1;
5717 pmm_free_blocks((*t).data as u64, pages as u64);
5718 pmm_free_blocks(t as u64, 1);
5719 }
5720
5721 fn tensor_matmul(a: ptr<Tensor2D>, b: ptr<Tensor2D>, out: ptr<Tensor2D>) {
5722 if (*a).cols != (*b).rows { return; }
5723 if (*out).rows != (*a).rows || (*out).cols != (*b).cols { return; }
5724
5725 for i in 0..(*a).rows {
5726 for j in 0..(*b).cols {
5727 let mut sum: f32 = 0.0;
5728 for k in 0..(*a).cols {
5729 let val_a = *((*a).data as u64 + (i * (*a).cols + k) as u64 * 4) as ptr<f32>;
5730 let val_b = *((*b).data as u64 + (k * (*b).cols + j) as u64 * 4) as ptr<f32>;
5731 sum = sum + (*val_a * *val_b);
5732 }
5733 *((*out).data as u64 + (i * (*out).cols + j) as u64 * 4) as ptr<f32> = sum;
5734 }
5735 }
5736 }
5737
5738 fn tensor_relu(t: ptr<Tensor2D>) {
5739 let total = (*t).rows * (*t).cols;
5740 for i in 0..total {
5741 let val_ptr = ((*t).data as u64 + i as u64 * 4) as ptr<f32>;
5742 if *val_ptr < 0.0 {
5743 *val_ptr = 0.0;
5744 }
5745 }
5746 }
5747
5748 fn tensor_sigmoid(t: ptr<Tensor2D>) {
5749 let total = (*t).rows * (*t).cols;
5750 for i in 0..total {
5751 let val_ptr = ((*t).data as u64 + i as u64 * 4) as ptr<f32>;
5752 let e_x = math_exp(-(*val_ptr));
5753 *val_ptr = 1.0 / (1.0 + e_x);
5754 }
5755 }
5756
5757 fn tensor_softmax(t: ptr<Tensor2D>) {
5758 for i in 0..(*t).rows {
5759 let mut max_val = *((*t).data as u64 + (i * (*t).cols) as u64 * 4) as ptr<f32>;
5760 for j in 1..(*t).cols {
5761 let v = *((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5762 if v > max_val { max_val = v; }
5763 }
5764
5765 let mut sum_exp: f32 = 0.0;
5766 for j in 0..(*t).cols {
5767 let val_ptr = ((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5768 let e = math_exp(*val_ptr - max_val);
5769 *val_ptr = e;
5770 sum_exp = sum_exp + e;
5771 }
5772
5773 for j in 0..(*t).cols {
5774 let val_ptr = ((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5775 *val_ptr = *val_ptr / sum_exp;
5776 }
5777 }
5778 }
5779
5780 const FW_ACTION_ALLOW: u8 = 0;
5781 const FW_ACTION_DROP: u8 = 1;
5782 const FW_ACTION_REJECT: u8 = 2;
5783
5784 const FW_PROTO_TCP: u8 = 6;
5785 const FW_PROTO_UDP: u8 = 17;
5786 const FW_PROTO_ICMP: u8 = 1;
5787
5788 struct FirewallRule {
5789 src_ip: Ipv4Addr,
5790 src_mask: Ipv4Addr,
5791 dst_ip: Ipv4Addr,
5792 dst_mask: Ipv4Addr,
5793 src_port_min: u16,
5794 src_port_max: u16,
5795 dst_port_min: u16,
5796 dst_port_max: u16,
5797 protocol: u8,
5798 action: u8,
5799 is_active: bool,
5800 hit_count: u64,
5801 }
5802
5803 struct FwConnectionState {
5804 src_ip: Ipv4Addr,
5805 dst_ip: Ipv4Addr,
5806 src_port: u16,
5807 dst_port: u16,
5808 protocol: u8,
5809 state: u8,
5810 last_activity: u64,
5811 is_active: bool,
5812 }
5813
5814 let mut global_fw_rules: [FirewallRule; 512];
5815 let mut global_fw_states: [FwConnectionState; 4096];
5816 let mut fw_lock: Spinlock;
5817 let mut fw_enabled: bool = true;
5818 let mut fw_syn_cookie_secret: u32 = 0;
5819
5820 fn fw_init() {
5821 spin_init(&fw_lock);
5822 for i in 0..512 { global_fw_rules[i].is_active = false; }
5823 for i in 0..4096 { global_fw_states[i].is_active = false; }
5824 fw_syn_cookie_secret = rand_next() as u32;
5825 }
5826
5827 fn fw_add_rule(src_ip: Ipv4Addr, src_mask: Ipv4Addr, dst_ip: Ipv4Addr, dst_mask: Ipv4Addr, p_min: u16, p_max: u16, proto: u8, action: u8) -> bool {
5828 spin_lock(&fw_lock);
5829 for i in 0..512 {
5830 if !global_fw_rules[i].is_active {
5831 global_fw_rules[i].src_ip = src_ip;
5832 global_fw_rules[i].src_mask = src_mask;
5833 global_fw_rules[i].dst_ip = dst_ip;
5834 global_fw_rules[i].dst_mask = dst_mask;
5835 global_fw_rules[i].src_port_min = 0;
5836 global_fw_rules[i].src_port_max = 65535;
5837 global_fw_rules[i].dst_port_min = p_min;
5838 global_fw_rules[i].dst_port_max = p_max;
5839 global_fw_rules[i].protocol = proto;
5840 global_fw_rules[i].action = action;
5841 global_fw_rules[i].hit_count = 0;
5842 global_fw_rules[i].is_active = true;
5843 spin_unlock(&fw_lock);
5844 return true;
5845 }
5846 }
5847 spin_unlock(&fw_lock);
5848 return false;
5849 }
5850
5851 fn fw_match_ip(ip: Ipv4Addr, rule_ip: Ipv4Addr, mask: Ipv4Addr) -> bool {
5852 for i in 0..4 {
5853 if (ip.addr[i] & mask.addr[i]) != (rule_ip.addr[i] & mask.addr[i]) {
5854 return false;
5855 }
5856 }
5857 return true;
5858 }
5859
5860 fn fw_track_connection(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, src_port: u16, dst_port: u16, proto: u8, tcp_flags: u16) -> bool {
5861 for i in 0..4096 {
5862 if global_fw_states[i].is_active {
5863 let mut match_fwd = true;
5864 let mut match_rev = true;
5865 for j in 0..4 {
5866 if global_fw_states[i].src_ip.addr[j] != src_ip.addr[j] || global_fw_states[i].dst_ip.addr[j] != dst_ip.addr[j] { match_fwd = false; }
5867 if global_fw_states[i].src_ip.addr[j] != dst_ip.addr[j] || global_fw_states[i].dst_ip.addr[j] != src_ip.addr[j] { match_rev = false; }
5868 }
5869 if global_fw_states[i].protocol != proto { match_fwd = false; match_rev = false; }
5870 if global_fw_states[i].src_port != src_port || global_fw_states[i].dst_port != dst_port { match_fwd = false; }
5871 if global_fw_states[i].src_port != dst_port || global_fw_states[i].dst_port != src_port { match_rev = false; }
5872
5873 if match_fwd || match_rev {
5874 global_fw_states[i].last_activity = current_time_tick;
5875 if proto == FW_PROTO_TCP && (tcp_flags & 0x01) != 0 {
5876 global_fw_states[i].is_active = false;
5877 }
5878 return true;
5879 }
5880 }
5881 }
5882
5883 if proto == FW_PROTO_TCP && (tcp_flags & 0x02) != 0 && (tcp_flags & 0x10) == 0 {
5884 for i in 0..4096 {
5885 if !global_fw_states[i].is_active {
5886 global_fw_states[i].src_ip = src_ip;
5887 global_fw_states[i].dst_ip = dst_ip;
5888 global_fw_states[i].src_port = src_port;
5889 global_fw_states[i].dst_port = dst_port;
5890 global_fw_states[i].protocol = proto;
5891 global_fw_states[i].state = 1;
5892 global_fw_states[i].last_activity = current_time_tick;
5893 global_fw_states[i].is_active = true;
5894 return true;
5895 }
5896 }
5897 }
5898
5899 return false;
5900 }
5901
5902 fn fw_inspect_packet(packet: ptr<u8>, length: u32) -> u8 {
5903 if !fw_enabled { return FW_ACTION_ALLOW; }
5904
5905 let eth = packet as ptr<EthernetHeader>;
5906 if htons((*eth).ethertype) != 0x0800 { return FW_ACTION_ALLOW; }
5907
5908 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
5909 let proto = (*iph).protocol;
5910 let mut src_port: u16 = 0;
5911 let mut dst_port: u16 = 0;
5912 let mut tcp_flags: u16 = 0;
5913
5914 if proto == FW_PROTO_TCP {
5915 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
5916 src_port = htons((*tcph).src_port);
5917 dst_port = htons((*tcph).dest_port);
5918 tcp_flags = htons((*tcph).data_offset_flags) & 0x01FF;
5919 } else if proto == FW_PROTO_UDP {
5920 let udph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<UdpHeader>;
5921 src_port = htons((*udph).src_port);
5922 dst_port = htons((*udph).dest_port);
5923 }
5924
5925 spin_lock(&fw_lock);
5926 let tracked = fw_track_connection((*iph).src_ip, (*iph).dest_ip, src_port, dst_port, proto, tcp_flags);
5927 if tracked {
5928 spin_unlock(&fw_lock);
5929 return FW_ACTION_ALLOW;
5930 }
5931
5932 let mut final_action = FW_ACTION_DROP;
5933
5934 for i in 0..512 {
5935 if global_fw_rules[i].is_active {
5936 let mut match_rule = true;
5937 if global_fw_rules[i].protocol != 0 && global_fw_rules[i].protocol != proto { match_rule = false; }
5938 if !fw_match_ip((*iph).src_ip, global_fw_rules[i].src_ip, global_fw_rules[i].src_mask) { match_rule = false; }
5939 if !fw_match_ip((*iph).dest_ip, global_fw_rules[i].dst_ip, global_fw_rules[i].dst_mask) { match_rule = false; }
5940 if proto == FW_PROTO_TCP || proto == FW_PROTO_UDP {
5941 if src_port < global_fw_rules[i].src_port_min || src_port > global_fw_rules[i].src_port_max { match_rule = false; }
5942 if dst_port < global_fw_rules[i].dst_port_min || dst_port > global_fw_rules[i].dst_port_max { match_rule = false; }
5943 }
5944
5945 if match_rule {
5946 global_fw_rules[i].hit_count = global_fw_rules[i].hit_count + 1;
5947 final_action = global_fw_rules[i].action;
5948 break;
5949 }
5950 }
5951 }
5952
5953 spin_unlock(&fw_lock);
5954 return final_action;
5955 }
5956
5957 struct HciCommandHeader {
5958 opcode: u16,
5959 param_length: u8,
5960 }
5961
5962 struct HciAclHeader {
5963 handle_flags: u16,
5964 data_length: u16,
5965 }
5966
5967 struct L2capHeader {
5968 length: u16,
5969 channel_id: u16,
5970 }
5971
5972 const HCI_CMD_RESET: u16 = 0x0C03;
5973 const HCI_CMD_READ_BD_ADDR: u16 = 0x1009;
5974 const HCI_CMD_INQUIRY: u16 = 0x0401;
5975 const HCI_CMD_CREATE_CONNECTION: u16 = 0x0405;
5976
5977 let mut bt_hci_tx_ring: ptr<u8>;
5978 let mut bt_hci_rx_ring: ptr<u8>;
5979
5980 fn bt_init_controller() {
5981 bt_hci_tx_ring = pmm_alloc_blocks(1) as ptr<u8>;
5982 bt_hci_rx_ring = pmm_alloc_blocks(1) as ptr<u8>;
5983 memset(bt_hci_tx_ring, 0, PAGE_SIZE);
5984 memset(bt_hci_rx_ring, 0, PAGE_SIZE);
5985 }
5986
5987 fn bt_send_hci_command(opcode: u16, params: ptr<u8>, param_len: u8) {
5988 let hdr = bt_hci_tx_ring as ptr<HciCommandHeader>;
5989 (*hdr).opcode = opcode;
5990 (*hdr).param_length = param_len;
5991 if param_len > 0 {
5992 let payload = (bt_hci_tx_ring as u64 + sizeof(HciCommandHeader) as u64) as ptr<u8>;
5993 memcpy(payload, params, param_len as u64);
5994 }
5995 let total_len = sizeof(HciCommandHeader) as u64 + param_len as u64;
5996 xhci_queue_isoch_transfer(0 as ptr<u8>, bt_hci_tx_ring as u64, total_len as u32, 0);
5997 }
5998
5999 fn bt_send_l2cap(handle: u16, cid: u16, data: ptr<u8>, len: u16) {
6000 let acl_hdr = bt_hci_tx_ring as ptr<HciAclHeader>;
6001 (*acl_hdr).handle_flags = handle | 0x2000;
6002 (*acl_hdr).data_length = sizeof(L2capHeader) as u16 + len;
6003
6004 let l2cap_hdr = (bt_hci_tx_ring as u64 + sizeof(HciAclHeader) as u64) as ptr<L2capHeader>;
6005 (*l2cap_hdr).length = len;
6006 (*l2cap_hdr).channel_id = cid;
6007
6008 let payload = (bt_hci_tx_ring as u64 + sizeof(HciAclHeader) as u64 + sizeof(L2capHeader) as u64) as ptr<u8>;
6009 memcpy(payload, data, len as u64);
6010
6011 let total_len = sizeof(HciAclHeader) as u64 + (*acl_hdr).data_length as u64;
6012 xhci_queue_isoch_transfer(0 as ptr<u8>, bt_hci_tx_ring as u64, total_len as u32, 0);
6013 }
6014
6015 struct Jbd2Header {
6016 h_magic: u32,
6017 h_blocktype: u32,
6018 h_sequence: u32,
6019 }
6020
6021 struct Jbd2BlockTag {
6022 t_blocknr: u32,
6023 t_flags: u16,
6024 }
6025
6026 const JBD2_MAGIC_NUMBER: u32 = 0xC03B3998;
6027 const JBD2_DESCRIPTOR_BLOCK: u32 = 1;
6028 const JBD2_COMMIT_BLOCK: u32 = 2;
6029 const JBD2_SUPERBLOCK_V1: u32 = 3;
6030 const JBD2_SUPERBLOCK_V2: u32 = 4;
6031 const JBD2_REVOKE_BLOCK: u32 = 5;
6032
6033 let mut jbd2_journal_start: u32 = 0;
6034 let mut jbd2_journal_end: u32 = 0;
6035 let mut jbd2_current_seq: u32 = 1;
6036
6037 fn jbd2_init(start_block: u32, end_block: u32) {
6038 jbd2_journal_start = start_block;
6039 jbd2_journal_end = end_block;
6040 jbd2_current_seq = 1;
6041 }
6042
6043 fn jbd2_start_transaction() -> u32 {
6044 let seq = jbd2_current_seq;
6045 jbd2_current_seq = jbd2_current_seq + 1;
6046 return seq;
6047 }
6048
6049 fn jbd2_write_descriptor(seq: u32, target_blocks: ptr<u32>, count: u32) -> u32 {
6050 let buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
6051 memset(buf, 0, ext2_block_size as u64);
6052
6053 let hdr = buf as ptr<Jbd2Header>;
6054 (*hdr).h_magic = htonl(JBD2_MAGIC_NUMBER);
6055 (*hdr).h_blocktype = htonl(JBD2_DESCRIPTOR_BLOCK);
6056 (*hdr).h_sequence = htonl(seq);
6057
6058 let mut offset = sizeof(Jbd2Header) as u64;
6059 for i in 0..count {
6060 let tag = (buf as u64 + offset) as ptr<Jbd2BlockTag>;
6061 (*tag).t_blocknr = htonl(*(target_blocks as u64 + i as u64 * 4) as ptr<u32>);
6062 (*tag).t_flags = 0;
6063 if i == count - 1 { (*tag).t_flags = htons(8); }
6064 offset = offset + sizeof(Jbd2BlockTag) as u64;
6065 }
6066
6067 let lba = fat32_cluster_to_lba(jbd2_journal_start);
6068 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, lba as u64, (ext2_block_size / 512) as u32, buf as u64);
6069 pmm_free_blocks(buf as u64, (ext2_block_size / PAGE_SIZE as u32) + 1);
6070 return jbd2_journal_start + 1;
6071 }
6072
6073 fn jbd2_commit_transaction(seq: u32, cur_journal_block: u32) {
6074 let buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
6075 memset(buf, 0, ext2_block_size as u64);
6076
6077 let hdr = buf as ptr<Jbd2Header>;
6078 (*hdr).h_magic = htonl(JBD2_MAGIC_NUMBER);
6079 (*hdr).h_blocktype = htonl(JBD2_COMMIT_BLOCK);
6080 (*hdr).h_sequence = htonl(seq);
6081
6082 let lba = fat32_cluster_to_lba(cur_journal_block);
6083 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, lba as u64, (ext2_block_size / 512) as u32, buf as u64);
6084 pmm_free_blocks(buf as u64, (ext2_block_size / PAGE_SIZE as u32) + 1);
6085 }
6086
6087 struct UacFormatTypeI {
6088 length: u8,
6089 descriptor_type: u8,
6090 descriptor_subtype: u8,
6091 format_type: u8,
6092 num_channels: u8,
6093 subframe_size: u8,
6094 bit_resolution: u8,
6095 sample_freq_type: u8,
6096 sample_freq: [u8; 3],
6097 }
6098
6099 fn uac_set_sample_rate(ep_addr: u8, rate: u32) {
6100 let mut setup_packet: [u8; 8];
6101 setup_packet[0] = 0x22;
6102 setup_packet[1] = 0x01;
6103 setup_packet[2] = 0x01;
6104 setup_packet[3] = 0x01;
6105 setup_packet[4] = ep_addr;
6106 setup_packet[5] = 0x00;
6107 setup_packet[6] = 0x03;
6108 setup_packet[7] = 0x00;
6109
6110 let mut data_packet: [u8; 3];
6111 data_packet[0] = (rate & 0xFF) as u8;
6112 data_packet[1] = ((rate >> 8) & 0xFF) as u8;
6113 data_packet[2] = ((rate >> 16) & 0xFF) as u8;
6114 }
6115
6116 fn hw_rdrand_64() -> u64 {
6117 let mut val: u64 = 0;
6118 let mut retry: u32 = 10;
6119 while retry > 0 {
6120 let mut success: u8 = 0;
6121 asm {
6122 "rdrand rax\n setc bl"
6123 out rax = val;
6124 out bl = success;
6125 }
6126 if success == 1 { return val; }
6127 retry = retry - 1;
6128 }
6129 return rand_next();
6130 }
6131
6132 fn hw_rdseed_64() -> u64 {
6133 let mut val: u64 = 0;
6134 let mut retry: u32 = 10;
6135 while retry > 0 {
6136 let mut success: u8 = 0;
6137 asm {
6138 "rdseed rax\n setc bl"
6139 out rax = val;
6140 out bl = success;
6141 }
6142 if success == 1 { return val; }
6143 retry = retry - 1;
6144 }
6145 return hw_rdrand_64();
6146 }
6147
6148 struct VmxonRegion {
6149 revision_id: u32,
6150 data: [u8; 4092],
6151 }
6152
6153 struct VmcsRegion {
6154 revision_id: u32,
6155 abort_indicator: u32,
6156 data: [u8; 4088],
6157 }
6158
6159 let mut vmx_enabled: bool = false;
6160 let mut vmxon_region_phys: u64 = 0;
6161
6162 fn vmx_check_support() -> bool {
6163 let mut ecx: u32 = 0;
6164 asm {
6165 "mov eax, 1\n cpuid"
6166 out ecx = ecx;
6167 }
6168 return (ecx & (1 << 5)) != 0;
6169 }
6170
6171 fn vmx_enable() {
6172 let mut cr4: u64 = 0;
6173 asm { "mov %0, cr4" out cr4 = cr4; }
6174 cr4 |= (1 << 13);
6175 asm { "mov cr4, %0" in "%0" = cr4; }
6176
6177 let feature_control = rdmsr(0x3A);
6178 if (feature_control & 1) == 0 {
6179 wrmsr(0x3A, feature_control | 5);
6180 }
6181 }
6182
6183 fn vmx_init() {
6184 if !vmx_check_support() { return; }
6185 vmx_enable();
6186
6187 let vmx_basic = rdmsr(0x480);
6188 let revision_id = (vmx_basic & 0xFFFFFFFF) as u32;
6189
6190 vmxon_region_phys = pmm_alloc_blocks(1);
6191 memset(vmxon_region_phys as ptr<u8>, 0, PAGE_SIZE);
6192 *(vmxon_region_phys as ptr<u32>) = revision_id;
6193
6194 let mut success: u8 = 0;
6195 asm {
6196 "vmxon [%0]\n setz al\n setc ah"
6197 in "%0" = &vmxon_region_phys;
6198 out al = success;
6199 }
6200 if success == 0 { vmx_enabled = true; }
6201 }
6202
6203 fn vmx_create_vm() -> ptr<VmcsRegion> {
6204 if !vmx_enabled { return 0 as ptr<VmcsRegion>; }
6205
6206 let vmx_basic = rdmsr(0x480);
6207 let revision_id = (vmx_basic & 0xFFFFFFFF) as u32;
6208
6209 let vmcs_phys = pmm_alloc_blocks(1);
6210 memset(vmcs_phys as ptr<u8>, 0, PAGE_SIZE);
6211 *(vmcs_phys as ptr<u32>) = revision_id;
6212
6213 asm {
6214 "vmclear [%0]"
6215 in "%0" = &vmcs_phys;
6216 }
6217
6218 asm {
6219 "vmptrld [%0]"
6220 in "%0" = &vmcs_phys;
6221 }
6222
6223 return vmcs_phys as ptr<VmcsRegion>;
6224 }
6225
6226 struct WasmModule {
6227 magic: u32,
6228 version: u32,
6229 memory_pages: u32,
6230 memory_base: u64,
6231 code_base: ptr<u8>,
6232 code_size: u64,
6233 }
6234
6235 const WASM_MAGIC: u32 = 0x6D736100;
6236
6237 fn wasm_parse_leb128(data: ptr<u8>, offset: ptr<u64>) -> u64 {
6238 let mut result: u64 = 0;
6239 let mut shift: u64 = 0;
6240 loop {
6241 let byte = *(data as u64 + *offset) as ptr<u8>;
6242 *offset = *offset + 1;
6243 result |= ((*byte & 0x7F) as u64) << shift;
6244 shift = shift + 7;
6245 if (*byte & 0x80) == 0 { break; }
6246 }
6247 return result;
6248 }
6249
6250 fn wasm_load_module(wasm_data: ptr<u8>, size: u64) -> ptr<WasmModule> {
6251 let magic = *(wasm_data as ptr<u32>);
6252 if magic != WASM_MAGIC { return 0 as ptr<WasmModule>; }
6253
6254 let version = *((wasm_data as u64 + 4) as ptr<u32>);
6255 if version != 1 { return 0 as ptr<WasmModule>; }
6256
6257 let module = pmm_alloc_blocks(1) as ptr<WasmModule>;
6258 memset(module as ptr<u8>, 0, sizeof(WasmModule) as u64);
6259 (*module).magic = magic;
6260 (*module).version = version;
6261
6262 let mut offset: u64 = 8;
6263 while offset < size {
6264 let section_id = *(wasm_data as u64 + offset) as ptr<u8>;
6265 offset = offset + 1;
6266 let section_size = wasm_parse_leb128(wasm_data, &offset);
6267
6268 if *section_id == 10 {
6269 (*module).code_base = (wasm_data as u64 + offset) as ptr<u8>;
6270 (*module).code_size = section_size;
6271 } else if *section_id == 5 {
6272 let _num_mems = wasm_parse_leb128(wasm_data, &offset);
6273 let flags = wasm_parse_leb128(wasm_data, &offset);
6274 let initial_pages = wasm_parse_leb128(wasm_data, &offset);
6275 (*module).memory_pages = initial_pages as u32;
6276 (*module).memory_base = pmm_alloc_blocks(initial_pages * 16);
6277 memset((*module).memory_base as ptr<u8>, 0, initial_pages * 65536);
6278 }
6279 offset = offset + section_size;
6280 }
6281 return module;
6282 }
6283
6284 fn wasm_execute_function(module: ptr<WasmModule>, func_offset: u64) {
6285 let mut pc = func_offset;
6286 let mut stack: [u64; 1024];
6287 let mut sp: u32 = 0;
6288
6289 let code = (*module).code_base;
6290 loop {
6291 let opcode = *(code as u64 + pc) as ptr<u8>;
6292 pc = pc + 1;
6293
6294 if *opcode == 0x0B {
6295 break;
6296 } else if *opcode == 0x20 {
6297 let local_idx = wasm_parse_leb128(code, &pc);
6298 stack[sp as usize] = 0;
6299 sp = sp + 1;
6300 } else if *opcode == 0x41 {
6301 let val = wasm_parse_leb128(code, &pc);
6302 stack[sp as usize] = val;
6303 sp = sp + 1;
6304 } else if *opcode == 0x6A {
6305 sp = sp - 1; let b = stack[sp as usize] as i32;
6306 sp = sp - 1; let a = stack[sp as usize] as i32;
6307 stack[sp as usize] = (a + b) as u64;
6308 sp = sp + 1;
6309 } else if *opcode == 0x6B {
6310 sp = sp - 1; let b = stack[sp as usize] as i32;
6311 sp = sp - 1; let a = stack[sp as usize] as i32;
6312 stack[sp as usize] = (a - b) as u64;
6313 sp = sp + 1;
6314 } else if *opcode == 0x6C {
6315 sp = sp - 1; let b = stack[sp as usize] as i32;
6316 sp = sp - 1; let a = stack[sp as usize] as i32;
6317 stack[sp as usize] = (a * b) as u64;
6318 sp = sp + 1;
6319 }
6320 }
6321 }
6322
6323 const DB_TYPE_STRING: u8 = 1;
6324 const DB_TYPE_LIST: u8 = 2;
6325 const DB_TYPE_INT: u8 = 3;
6326
6327 struct AegisDbEntry {
6328 key: [u8; 32],
6329 val_type: u8,
6330 val_int: u64,
6331 val_str: ptr<u8>,
6332 val_size: u64,
6333 next: ptr<AegisDbEntry>,
6334 }
6335
6336 let mut global_db_hash_table: [ptr<AegisDbEntry>; 1024];
6337 let mut db_lock: Spinlock;
6338
6339 fn db_hash_key(key: ptr<u8>) -> u32 {
6340 let mut hash: u32 = 5381;
6341 let mut i: u64 = 0;
6342 while *(key + i) != 0 {
6343 hash = ((hash << 5) + hash) + (*(key + i) as u32);
6344 i = i + 1;
6345 }
6346 return hash % 1024;
6347 }
6348
6349 fn db_init() {
6350 spin_init(&db_lock);
6351 for i in 0..1024 {
6352 global_db_hash_table[i] = 0 as ptr<AegisDbEntry>;
6353 }
6354 }
6355
6356 fn db_set_string(key: ptr<u8>, value: ptr<u8>) {
6357 spin_lock(&db_lock);
6358 let idx = db_hash_key(key);
6359
6360 let mut curr = global_db_hash_table[idx as usize];
6361 while curr != 0 as ptr<AegisDbEntry> {
6362 if strcmp(&((*curr).key[0]) as ptr<u8>, key) == 0 {
6363 if (*curr).val_str != 0 as ptr<u8> {
6364 pmm_free_blocks((*curr).val_str as u64, ((*curr).val_size / PAGE_SIZE) + 1);
6365 }
6366 let len = strlen(value) + 1;
6367 (*curr).val_type = DB_TYPE_STRING;
6368 (*curr).val_size = len;
6369 (*curr).val_str = pmm_alloc_blocks((len / PAGE_SIZE) + 1) as ptr<u8>;
6370 strcpy((*curr).val_str, value);
6371 spin_unlock(&db_lock);
6372 return;
6373 }
6374 curr = (*curr).next;
6375 }
6376
6377 let new_entry = pmm_alloc_blocks(1) as ptr<AegisDbEntry>;
6378 memset(new_entry as ptr<u8>, 0, sizeof(AegisDbEntry) as u64);
6379 strcpy(&((*new_entry).key[0]) as ptr<u8>, key);
6380 let len = strlen(value) + 1;
6381 (*new_entry).val_type = DB_TYPE_STRING;
6382 (*new_entry).val_size = len;
6383 (*new_entry).val_str = pmm_alloc_blocks((len / PAGE_SIZE) + 1) as ptr<u8>;
6384 strcpy((*new_entry).val_str, value);
6385
6386 (*new_entry).next = global_db_hash_table[idx as usize];
6387 global_db_hash_table[idx as usize] = new_entry;
6388 spin_unlock(&db_lock);
6389 }
6390
6391 fn db_get_string(key: ptr<u8>, out_buf: ptr<u8>) -> bool {
6392 spin_lock(&db_lock);
6393 let idx = db_hash_key(key);
6394 let mut curr = global_db_hash_table[idx as usize];
6395 while curr != 0 as ptr<AegisDbEntry> {
6396 if strcmp(&((*curr).key[0]) as ptr<u8>, key) == 0 && (*curr).val_type == DB_TYPE_STRING {
6397 strcpy(out_buf, (*curr).val_str);
6398 spin_unlock(&db_lock);
6399 return true;
6400 }
6401 curr = (*curr).next;
6402 }
6403 spin_unlock(&db_lock);
6404 return false;
6405 }
6406
6407 const PTRACE_TRACEME: u32 = 0;
6408 const PTRACE_PEEKTEXT: u32 = 1;
6409 const PTRACE_POKETEXT: u32 = 4;
6410 const PTRACE_CONT: u32 = 7;
6411 const PTRACE_SINGLESTEP: u32 = 9;
6412 const PTRACE_GETREGS: u32 = 12;
6413 const PTRACE_SETREGS: u32 = 13;
6414 const PTRACE_ATTACH: u32 = 16;
6415 const PTRACE_DETACH: u32 = 17;
6416
6417 struct PtraceState {
6418 is_traced: bool,
6419 tracer_pid: u64,
6420 stop_signal: u32,
6421 saved_opcode: u8,
6422 breakpoint_addr: u64,
6423 }
6424
6425 fn ptrace_attach(target_pid: u64, tracer_pid: u64) -> i32 {
6426 let mut curr = process_queue;
6427 while curr != 0 as ptr<ProcessControlBlock> {
6428 if (*curr).pid == target_pid {
6429 let proc_ext = curr as ptr<ProcessControlBlockExt>;
6430 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
6431 if (*pstate).is_traced { return -1; }
6432 (*pstate).is_traced = true;
6433 (*pstate).tracer_pid = tracer_pid;
6434 signal_send(target_pid, 19);
6435 return 0;
6436 }
6437 curr = (*curr).next;
6438 }
6439 return -1;
6440 }
6441
6442 fn ptrace_getregs(target_pid: u64, out_ctx: ptr<CpuContext>) -> i32 {
6443 let mut curr = process_queue;
6444 while curr != 0 as ptr<ProcessControlBlock> {
6445 if (*curr).pid == target_pid {
6446 let proc_ext = curr as ptr<ProcessControlBlockExt>;
6447 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
6448 if !(*pstate).is_traced { return -1; }
6449 memcpy(out_ctx as ptr<u8>, (*curr).context as ptr<u8>, sizeof(CpuContext) as u64);
6450 return 0;
6451 }
6452 curr = (*curr).next;
6453 }
6454 return -1;
6455 }
6456
6457 fn ptrace_set_breakpoint(target_pid: u64, addr: u64) -> i32 {
6458 let mut curr = process_queue;
6459 while curr != 0 as ptr<ProcessControlBlock> {
6460 if (*curr).pid == target_pid {
6461 let proc_ext = curr as ptr<ProcessControlBlockExt>;
6462 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
6463 if !(*pstate).is_traced { return -1; }
6464
6465 let old_cr3 = rdmsr(0);
6466 asm { "mov cr3, %0" in "%0" = (*curr).cr3_phys; }
6467
6468 (*pstate).saved_opcode = *(addr as ptr<u8>);
6469 *(addr as ptr<u8>) = 0xCC;
6470 (*pstate).breakpoint_addr = addr;
6471
6472 asm { "mov cr3, %0" in "%0" = old_cr3; }
6473 return 0;
6474 }
6475 curr = (*curr).next;
6476 }
6477 return -1;
6478 }
6479
6480 fn exc_breakpoint_handler_adv() {
6481 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
6482 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
6483
6484 if (*pstate).is_traced {
6485 (*current_process).state = 0;
6486 let rip = (*(*current_process).context).rip - 1;
6487
6488 if rip == (*pstate).breakpoint_addr {
6489 *(rip as ptr<u8>) = (*pstate).saved_opcode;
6490 (*(*current_process).context).rip = rip;
6491 }
6492
6493 signal_send((*pstate).tracer_pid, 17);
6494 scheduler_tick();
6495 }
6496 }
6497
6498 const MSR_IA32_PERF_GLOBAL_CTRL: u32 = 0x38F;
6499 const MSR_IA32_PERFEVTSEL0: u32 = 0x186;
6500 const MSR_IA32_PERFEVTSEL1: u32 = 0x187;
6501 const MSR_IA32_PMC0: u32 = 0xC1;
6502 const MSR_IA32_PMC1: u32 = 0xC2;
6503 const MSR_IA32_FIXED_CTR_CTRL: u32 = 0x38D;
6504 const MSR_IA32_FIXED_CTR0: u32 = 0x309;
6505 const MSR_IA32_FIXED_CTR1: u32 = 0x30A;
6506 const MSR_IA32_FIXED_CTR2: u32 = 0x30B;
6507
6508 struct PmuStats {
6509 instructions: u64,
6510 core_cycles: u64,
6511 ref_cycles: u64,
6512 cache_misses: u64,
6513 branch_misses: u64,
6514 }
6515
6516 let mut global_pmu_stats: PmuStats;
6517
6518 fn pmu_init() {
6519 let mut cpuid_eax: u32 = 0;
6520 let mut cpuid_ebx: u32 = 0;
6521 let mut cpuid_ecx: u32 = 0;
6522 let mut cpuid_edx: u32 = 0;
6523 cpuid(0x0A, 0, &mut cpuid_eax, &mut cpuid_ebx, &mut cpuid_ecx, &mut cpuid_edx);
6524 let pmu_version = cpuid_eax & 0xFF;
6525 if pmu_version < 2 { return; }
6526
6527 wrmsr(MSR_IA32_PERF_GLOBAL_CTRL, 0);
6528
6529 wrmsr(MSR_IA32_FIXED_CTR_CTRL, 0x333);
6530
6531 let evt_cache_miss = (0x41 << 8) | 0x2E | (1 << 16) | (1 << 22);
6532 wrmsr(MSR_IA32_PERFEVTSEL0, evt_cache_miss);
6533
6534 let evt_branch_miss = (0x00 << 8) | 0xC5 | (1 << 16) | (1 << 22);
6535 wrmsr(MSR_IA32_PERFEVTSEL1, evt_branch_miss);
6536
6537 wrmsr(MSR_IA32_PERF_GLOBAL_CTRL, (1 << 32) | (1 << 33) | (1 << 34) | 1 | 2);
6538 }
6539
6540 fn pmu_read_stats() {
6541 global_pmu_stats.instructions = rdmsr(MSR_IA32_FIXED_CTR0);
6542 global_pmu_stats.core_cycles = rdmsr(MSR_IA32_FIXED_CTR1);
6543 global_pmu_stats.ref_cycles = rdmsr(MSR_IA32_FIXED_CTR2);
6544 global_pmu_stats.cache_misses = rdmsr(MSR_IA32_PMC0);
6545 global_pmu_stats.branch_misses = rdmsr(MSR_IA32_PMC1);
6546 }
6547
6548 const EC_CMD_PORT: u16 = 0x66;
6549 const EC_DATA_PORT: u16 = 0x62;
6550 const EC_CMD_READ: u8 = 0x80;
6551 const EC_CMD_WRITE: u8 = 0x81;
6552 const EC_STAT_OBF: u8 = 0x01;
6553 const EC_STAT_IBF: u8 = 0x02;
6554
6555 fn acpi_ec_wait_write() {
6556 let mut timeout = 100000;
6557 while (inb(EC_CMD_PORT) & EC_STAT_IBF) != 0 && timeout > 0 {
6558 cpu_pause();
6559 timeout = timeout - 1;
6560 }
6561 }
6562
6563 fn acpi_ec_wait_read() {
6564 let mut timeout = 100000;
6565 while (inb(EC_CMD_PORT) & EC_STAT_OBF) == 0 && timeout > 0 {
6566 cpu_pause();
6567 timeout = timeout - 1;
6568 }
6569 }
6570
6571 fn acpi_ec_read(addr: u8) -> u8 {
6572 acpi_ec_wait_write();
6573 outb(EC_CMD_PORT, EC_CMD_READ);
6574 acpi_ec_wait_write();
6575 outb(EC_DATA_PORT, addr);
6576 acpi_ec_wait_read();
6577 return inb(EC_DATA_PORT);
6578 }
6579
6580 fn acpi_ec_write(addr: u8, data: u8) {
6581 acpi_ec_wait_write();
6582 outb(EC_CMD_PORT, EC_CMD_WRITE);
6583 acpi_ec_wait_write();
6584 outb(EC_DATA_PORT, addr);
6585 acpi_ec_wait_write();
6586 outb(EC_DATA_PORT, data);
6587 }
6588
6589 struct BatteryState {
6590 is_present: bool,
6591 is_charging: bool,
6592 capacity_percent: u8,
6593 voltage_mv: u16,
6594 temperature_c: u8,
6595 }
6596
6597 let mut global_battery_state: BatteryState;
6598
6599 fn acpi_update_battery_state() {
6600 let bat_status = acpi_ec_read(0x10);
6601 global_battery_state.is_present = (bat_status & 0x01) != 0;
6602 global_battery_state.is_charging = (bat_status & 0x02) != 0;
6603
6604 if global_battery_state.is_present {
6605 let cap_high = acpi_ec_read(0x11);
6606 let cap_low = acpi_ec_read(0x12);
6607 let max_cap = 10000;
6608 let current_cap = ((cap_high as u16) << 8) | (cap_low as u16);
6609 global_battery_state.capacity_percent = ((current_cap as u32 * 100) / max_cap as u32) as u8;
6610
6611 let volt_high = acpi_ec_read(0x13);
6612 let volt_low = acpi_ec_read(0x14);
6613 global_battery_state.voltage_mv = ((volt_high as u16) << 8) | (volt_low as u16);
6614
6615 let temp_raw = acpi_ec_read(0x15);
6616 global_battery_state.temperature_c = temp_raw - 27;
6617 }
6618 }
6619
6620 struct UsbHubDescriptor {
6621 length: u8,
6622 descriptor_type: u8,
6623 num_ports: u8,
6624 hub_characteristics: u16,
6625 power_on_to_power_good: u8,
6626 hub_control_current: u8,
6627 device_removable: u8,
6628 port_power_ctrl_mask: u8,
6629 }
6630
6631 struct UsbHubPort {
6632 port_id: u8,
6633 is_connected: bool,
6634 is_enabled: bool,
6635 is_superspeed: bool,
6636 device_address: u8,
6637 }
6638
6639 struct UsbHubDevice {
6640 address: u8,
6641 num_ports: u8,
6642 ports: [UsbHubPort; 16],
6643 is_active: bool,
6644 }
6645
6646 let mut global_usb_hubs: [UsbHubDevice; 8];
6647 let mut usb_hub_count: u32 = 0;
6648
6649 fn usb_hub_init_device(device_addr: u8) {
6650 if usb_hub_count >= 8 { return; }
6651
6652 let hub = &global_usb_hubs[usb_hub_count as usize];
6653 (*hub).address = device_addr;
6654 (*hub).is_active = true;
6655
6656 let desc_buf = pmm_alloc_blocks(1) as ptr<UsbHubDescriptor>;
6657
6658 let mut setup: [u8; 8];
6659 setup[0] = 0xA0;
6660 setup[1] = 0x06;
6661 setup[2] = 0x00;
6662 setup[3] = 0x29;
6663 setup[4] = 0x00;
6664 setup[5] = 0x00;
6665 setup[6] = sizeof(UsbHubDescriptor) as u8;
6666 setup[7] = 0x00;
6667
6668 (*hub).num_ports = (*desc_buf).num_ports;
6669 if (*hub).num_ports > 16 { (*hub).num_ports = 16; }
6670
6671 for p in 0..(*hub).num_ports {
6672 (*hub).ports[p as usize].port_id = p + 1;
6673 (*hub).ports[p as usize].is_connected = false;
6674
6675 setup[0] = 0x23;
6676 setup[1] = 0x03;
6677 setup[2] = 8;
6678 setup[3] = 0;
6679 setup[4] = p + 1;
6680 setup[5] = 0;
6681 setup[6] = 0;
6682 setup[7] = 0;
6683 }
6684
6685 usb_hub_count = usb_hub_count + 1;
6686 pmm_free_blocks(desc_buf as u64, 1);
6687 }
6688
6689 fn usb_hub_poll_ports() {
6690 for i in 0..usb_hub_count {
6691 let hub = &global_usb_hubs[i as usize];
6692 if (*hub).is_active {
6693 for p in 0..(*hub).num_ports {
6694
6695 let mut setup: [u8; 8];
6696 setup[0] = 0xA3;
6697 setup[1] = 0x00;
6698 setup[2] = 0x00;
6699 setup[3] = 0x00;
6700 setup[4] = (*hub).ports[p as usize].port_id;
6701 setup[5] = 0x00;
6702 setup[6] = 0x04;
6703 setup[7] = 0x00;
6704
6705 let mut status: u32 = 0;
6706
6707 let connected = (status & 0x0001) != 0;
6708 let connect_change = (status & 0x10000) != 0;
6709
6710 if connect_change {
6711
6712 setup[0] = 0x23; setup[1] = 0x01; setup[2] = 16; setup[4] = (*hub).ports[p as usize].port_id;
6713
6714 if connected && !(*hub).ports[p as usize].is_connected {
6715
6716 setup[0] = 0x23; setup[1] = 0x03; setup[2] = 4; setup[4] = (*hub).ports[p as usize].port_id;
6717 (*hub).ports[p as usize].is_connected = true;
6718 } else if !connected && (*hub).ports[p as usize].is_connected {
6719 (*hub).ports[p as usize].is_connected = false;
6720 (*hub).ports[p as usize].device_address = 0;
6721 }
6722 }
6723 }
6724 }
6725 }
6726 }
6727
6728 const SHADER_OP_NOP: u8 = 0;
6729 const SHADER_OP_MOV: u8 = 1;
6730 const SHADER_OP_ADD: u8 = 2;
6731 const SHADER_OP_MUL: u8 = 3;
6732 const SHADER_OP_DOT3: u8 = 4;
6733 const SHADER_OP_TEX: u8 = 5;
6734 const SHADER_OP_END: u8 = 255;
6735
6736 struct ShaderInstruction {
6737 opcode: u8,
6738 dest_reg: u8,
6739 src1_reg: u8,
6740 src2_reg: u8,
6741 }
6742
6743 struct GpuEuProgram {
6744 instructions: ptr<u32>,
6745 inst_count: u32,
6746 }
6747
6748 fn gpu_shader_compile(shader_src: ptr<ShaderInstruction>, count: u32) -> ptr<GpuEuProgram> {
6749 let prog = pmm_alloc_blocks(1) as ptr<GpuEuProgram>;
6750 let max_native_inst = count * 4;
6751 (*prog).instructions = pmm_alloc_blocks((max_native_inst * 4 / PAGE_SIZE as u32) + 1) as ptr<u32>;
6752 (*prog).inst_count = 0;
6753
6754 for i in 0..count {
6755 let inst = (shader_src as u64 + i as u64 * sizeof(ShaderInstruction) as u64) as ptr<ShaderInstruction>;
6756 let op = (*inst).opcode;
6757 let dst = (*inst).dest_reg;
6758 let s1 = (*inst).src1_reg;
6759 let s2 = (*inst).src2_reg;
6760
6761 let out_ptr = ((*prog).instructions as u64 + (*prog).inst_count as u64 * 4) as ptr<u32>;
6762
6763 if op == SHADER_OP_ADD {
6764 *out_ptr = 0x40000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6765 (*prog).inst_count = (*prog).inst_count + 1;
6766 } else if op == SHADER_OP_MUL {
6767 *out_ptr = 0x41000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6768 (*prog).inst_count = (*prog).inst_count + 1;
6769 } else if op == SHADER_OP_DOT3 {
6770 *out_ptr = 0x42000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6771 (*prog).inst_count = (*prog).inst_count + 1;
6772 } else if op == SHADER_OP_END {
6773 *out_ptr = 0xFFFFFFFF;
6774 (*prog).inst_count = (*prog).inst_count + 1;
6775 break;
6776 }
6777 }
6778 return prog;
6779 }
6780
6781 fn gpu_shader_bind(prog: ptr<GpuEuProgram>) {
6782 let phys_addr = (*prog).instructions as u64;
6783 intel_gpu_submit_cmd(0x71000000);
6784 intel_gpu_submit_cmd((phys_addr & 0xFFFFFFFF) as u32);
6785 intel_gpu_submit_cmd((phys_addr >> 32) as u32);
6786 intel_gpu_submit_cmd((*prog).inst_count * 4);
6787 }
6788
6789 fn chainload_mbr(drive_num: u8, partition_lba: u64) {
6790 let boot_sector = 0x7C00 as ptr<u8>;
6791
6792 ahci_read_sectors(global_raid_sys.disks[0].ahci_port, partition_lba, 1, boot_sector as u64);
6793
6794 let signature = *(0x7DFE as ptr<u16>);
6795 if signature != 0xAA55 {
6796 shell_print_string("Chainload failed: Invalid MBR signature.\n" as ptr<u8>);
6797 return;
6798 }
6799
6800 cpu_cli();
6801
6802 asm {
6803 "mov edx, %0\n"
6804 "jmp 0x0000:0x7C00"
6805 in "%0" = drive_num as u32;
6806 }
6807 }
6808
6809 struct Tpm2CrbControlArea {
6810 req: u32,
6811 sts: u32,
6812 cancel: u32,
6813 start: u32,
6814 int_ctrl: u64,
6815 cmd_size: u32,
6816 cmd_addr_low: u32,
6817 cmd_addr_high: u32,
6818 rsp_size: u32,
6819 rsp_addr_low: u32,
6820 rsp_addr_high: u32,
6821 }
6822
6823 struct Tpm2CmdHeader {
6824 tag: u16,
6825 param_size: u32,
6826 cmd_code: u32,
6827 }
6828
6829 let mut tpm2_crb_base: u64 = 0;
6830 let mut tpm2_ctrl_area: ptr<Tpm2CrbControlArea>;
6831 let mut tpm2_cmd_buf: ptr<u8>;
6832 let mut tpm2_rsp_buf: ptr<u8>;
6833
6834 fn tpm2_init(acpi_tpm2_base: u64) {
6835 tpm2_crb_base = acpi_tpm2_base;
6836 tpm2_ctrl_area = (tpm2_crb_base + 0x40) as ptr<Tpm2CrbControlArea>;
6837
6838 (*tpm2_ctrl_area).req = 1;
6839 while ((*tpm2_ctrl_area).sts & 1) == 0 { cpu_pause(); }
6840
6841 tpm2_cmd_buf = ((((*tpm2_ctrl_area).cmd_addr_high as u64) << 32) | (*tpm2_ctrl_area).cmd_addr_low as u64) as ptr<u8>;
6842 tpm2_rsp_buf = ((((*tpm2_ctrl_area).rsp_addr_high as u64) << 32) | (*tpm2_ctrl_area).rsp_addr_low as u64) as ptr<u8>;
6843 }
6844
6845 fn tpm2_send_command(cmd: ptr<u8>, size: u32) -> bool {
6846 memcpy(tpm2_cmd_buf, cmd, size as u64);
6847 (*tpm2_ctrl_area).start = 1;
6848
6849 let mut timeout = 1000000;
6850 while (*tpm2_ctrl_area).start != 0 && timeout > 0 {
6851 cpu_pause();
6852 timeout = timeout - 1;
6853 }
6854 return timeout > 0;
6855 }
6856
6857 fn tpm2_get_random(bytes: u16, out_buf: ptr<u8>) -> bool {
6858 let mut cmd: [u8; 12];
6859 let hdr = &cmd[0] as ptr<Tpm2CmdHeader>;
6860 (*hdr).tag = htons(0x8001);
6861 (*hdr).param_size = htonl(12);
6862 (*hdr).cmd_code = htonl(0x0000017B);
6863 cmd[10] = (bytes >> 8) as u8;
6864 cmd[11] = (bytes & 0xFF) as u8;
6865
6866 if !tpm2_send_command(&cmd[0] as ptr<u8>, 12) { return false; }
6867
6868 let rsp_tag = htons(*(tpm2_rsp_buf as ptr<u16>));
6869 let rsp_code = htonl(*((tpm2_rsp_buf as u64 + 6) as ptr<u32>));
6870 if rsp_code != 0 { return false; }
6871
6872 let out_size = htons(*((tpm2_rsp_buf as u64 + 10) as ptr<u16>));
6873 memcpy(out_buf, (tpm2_rsp_buf as u64 + 12) as ptr<u8>, out_size as u64);
6874 return true;
6875 }
6876
6877 fn rotl32(v: u32, c: u32) -> u32 { return (v << c) | (v >> (32 - c)); }
6878
6879 struct ChaCha20Ctx {
6880 state: [u32; 16],
6881 }
6882
6883 fn chacha20_init(ctx: ptr<ChaCha20Ctx>, key: ptr<u8>, nonce: ptr<u8>, counter: u32) {
6884 (*ctx).state[0] = 0x61707865;
6885 (*ctx).state[1] = 0x3320646e;
6886 (*ctx).state[2] = 0x79622d32;
6887 (*ctx).state[3] = 0x6b206574;
6888 for i in 0..8 {
6889 (*ctx).state[4 + i] = *((key as u64 + i as u64 * 4) as ptr<u32>);
6890 }
6891 (*ctx).state[12] = counter;
6892 for i in 0..3 {
6893 (*ctx).state[13 + i] = *((nonce as u64 + i as u64 * 4) as ptr<u32>);
6894 }
6895 }
6896
6897 fn chacha20_quarter_round(state: ptr<u32>, a: usize, b: usize, c: usize, d: usize) {
6898 let s = state;
6899 *(s.offset(a as isize)) = *(s.offset(a as isize)) + *(s.offset(b as isize)); *(s.offset(d as isize)) = rotl32(*(s.offset(d as isize)) ^ *(s.offset(a as isize)), 16);
6900 *(s.offset(c as isize)) = *(s.offset(c as isize)) + *(s.offset(d as isize)); *(s.offset(b as isize)) = rotl32(*(s.offset(b as isize)) ^ *(s.offset(c as isize)), 12);
6901 *(s.offset(a as isize)) = *(s.offset(a as isize)) + *(s.offset(b as isize)); *(s.offset(d as isize)) = rotl32(*(s.offset(d as isize)) ^ *(s.offset(a as isize)), 8);
6902 *(s.offset(c as isize)) = *(s.offset(c as isize)) + *(s.offset(d as isize)); *(s.offset(b as isize)) = rotl32(*(s.offset(b as isize)) ^ *(s.offset(c as isize)), 7);
6903 }
6904
6905 fn chacha20_block(ctx: ptr<ChaCha20Ctx>, out: ptr<u32>) {
6906 let mut working_state: [u32; 16];
6907 for i in 0..16 { working_state[i] = (*ctx).state[i]; }
6908
6909 for _ in 0..10 {
6910 chacha20_quarter_round(&working_state[0] as ptr<u32>, 0, 4, 8, 12);
6911 chacha20_quarter_round(&working_state[0] as ptr<u32>, 1, 5, 9, 13);
6912 chacha20_quarter_round(&working_state[0] as ptr<u32>, 2, 6, 10, 14);
6913 chacha20_quarter_round(&working_state[0] as ptr<u32>, 3, 7, 11, 15);
6914 chacha20_quarter_round(&working_state[0] as ptr<u32>, 0, 5, 10, 15);
6915 chacha20_quarter_round(&working_state[0] as ptr<u32>, 1, 6, 11, 12);
6916 chacha20_quarter_round(&working_state[0] as ptr<u32>, 2, 7, 8, 13);
6917 chacha20_quarter_round(&working_state[0] as ptr<u32>, 3, 4, 9, 14);
6918 }
6919
6920 for i in 0..16 { *(out as u64 + i as u64 * 4) as ptr<u32> = (*ctx).state[i] + working_state[i]; }
6921 (*ctx).state[12] = (*ctx).state[12] + 1;
6922 }
6923
6924 fn chacha20_encrypt(ctx: ptr<ChaCha20Ctx>, data: ptr<u8>, len: u64) {
6925 let mut i: u64 = 0;
6926 let mut block: [u32; 16];
6927 while i < len {
6928 chacha20_block(ctx, &block[0] as ptr<u32>);
6929 let block_u8 = &block[0] as ptr<u32> as ptr<u8>;
6930 let mut chunk = 64;
6931 if len - i < 64 { chunk = len - i; }
6932 for j in 0..chunk {
6933 *(data as u64 + i + j) = *(data as u64 + i + j) ^ *(block_u8 as u64 + j);
6934 }
6935 i = i + 64;
6936 }
6937 }
6938
6939 struct AvSignature {
6940 id: u32,
6941 name: [u8; 32],
6942 pattern: [u8; 16],
6943 pattern_len: u64,
6944 is_active: bool,
6945 }
6946
6947 let mut global_av_signatures: [AvSignature; 1024];
6948 let mut av_sig_count: u32 = 0;
6949
6950 fn av_init() {
6951 for i in 0..1024 { global_av_signatures[i].is_active = false; }
6952 }
6953
6954 fn av_add_signature(name: ptr<u8>, pattern: ptr<u8>, len: u64) {
6955 if av_sig_count >= 1024 { return; }
6956 let sig = &global_av_signatures[av_sig_count as usize];
6957 (*sig).id = av_sig_count;
6958 strcpy(&((*sig).name[0]) as ptr<u8>, name);
6959 memcpy(&((*sig).pattern[0]) as ptr<u8>, pattern, len);
6960 (*sig).pattern_len = len;
6961 (*sig).is_active = true;
6962 av_sig_count = av_sig_count + 1;
6963 }
6964
6965 fn av_scan_memory_region(start_addr: u64, length: u64) -> ptr<AvSignature> {
6966 let data = start_addr as ptr<u8>;
6967 for i in 0..av_sig_count {
6968 let sig = &global_av_signatures[i as usize];
6969 if (*sig).is_active {
6970 for j in 0..(length - (*sig).pattern_len) {
6971 let mut is_match = true;
6972 for k in 0..(*sig).pattern_len {
6973 if *(data as u64 + j + k) != (*sig).pattern[k as usize] {
6974 is_match = false;
6975 break;
6976 }
6977 }
6978 if is_match { return sig; }
6979 }
6980 }
6981 }
6982 return 0 as ptr<AvSignature>;
6983 }
6984
6985 fn av_monitor_process(pid: u64) {
6986 let mut curr = process_queue;
6987 while curr != 0 as ptr<ProcessControlBlock> {
6988 if (*curr).pid == pid {
6989 let proc_map = (curr as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<ProcessMemoryMap>;
6990 let mut vma = (*proc_map).vma_head;
6991 while vma != 0 as ptr<VmaNode> {
6992 if ((*vma).flags & 4) != 0 {
6993 let sig = av_scan_memory_region((*vma).start_vaddr, (*vma).end_vaddr - (*vma).start_vaddr);
6994 if sig != 0 as ptr<AvSignature> {
6995 shell_print_string("AEGIS-AV ALERT: Malicious code detected! PID: " as ptr<u8>);
6996 let mut buf: [u8; 16]; itoa(pid as i32, 10, &buf[0] as ptr<u8>);
6997 shell_print_string(&buf[0] as ptr<u8>);
6998 shell_print_string(" Threat: " as ptr<u8>);
6999 shell_print_string(&((*sig).name[0]) as ptr<u8>);
7000 shell_print_char(10);
7001 signal_send(pid, SIGKILL);
7002 return;
7003 }
7004 }
7005 vma = (*vma).next;
7006 }
7007 break;
7008 }
7009 curr = (*curr).next;
7010 }
7011 }
7012
7013 struct CowBlock {
7014 logical_block: u64,
7015 physical_block: u64,
7016 ref_count: u32,
7017 next: ptr<CowBlock>,
7018 }
7019
7020 struct CowSnapshot {
7021 snap_id: u32,
7022 timestamp: u64,
7023 blocks: ptr<CowBlock>,
7024 next: ptr<CowSnapshot>,
7025 }
7026
7027 let mut global_cow_mapping: ptr<CowBlock>;
7028 let mut global_snapshots: ptr<CowSnapshot>;
7029 let mut cow_next_snap_id: u32 = 1;
7030
7031 fn cow_init() {
7032 global_cow_mapping = 0 as ptr<CowBlock>;
7033 global_snapshots = 0 as ptr<CowSnapshot>;
7034 }
7035
7036 fn cow_get_physical(logical: u64) -> u64 {
7037 let mut curr = global_cow_mapping;
7038 while curr != 0 as ptr<CowBlock> {
7039 if (*curr).logical_block == logical { return (*curr).physical_block; }
7040 curr = (*curr).next;
7041 }
7042 return logical;
7043 }
7044
7045 fn cow_write_block(logical: u64, data_buf: u64) {
7046 let mut curr = global_cow_mapping;
7047 let mut target_node = 0 as ptr<CowBlock>;
7048
7049 while curr != 0 as ptr<CowBlock> {
7050 if (*curr).logical_block == logical { target_node = curr; break; }
7051 curr = (*curr).next;
7052 }
7053
7054 if target_node != 0 as ptr<CowBlock> && (*target_node).ref_count > 1 {
7055 (*target_node).ref_count = (*target_node).ref_count - 1;
7056 let new_phys = swap_alloc_slot() + 2000000;
7057
7058 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
7059 memset(new_node as ptr<u8>, 0, sizeof(CowBlock) as u64);
7060 (*new_node).logical_block = logical;
7061 (*new_node).physical_block = new_phys;
7062 (*new_node).ref_count = 1;
7063 (*new_node).next = global_cow_mapping;
7064 global_cow_mapping = new_node;
7065
7066 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, new_phys, 8, data_buf);
7067 } else if target_node != 0 as ptr<CowBlock> {
7068 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, (*target_node).physical_block, 8, data_buf);
7069 } else {
7070 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
7071 memset(new_node as ptr<u8>, 0, sizeof(CowBlock) as u64);
7072 (*new_node).logical_block = logical;
7073 (*new_node).physical_block = logical;
7074 (*new_node).ref_count = 1;
7075 (*new_node).next = global_cow_mapping;
7076 global_cow_mapping = new_node;
7077 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, logical, 8, data_buf);
7078 }
7079 }
7080
7081 fn cow_create_snapshot() -> u32 {
7082 let snap = pmm_alloc_blocks(1) as ptr<CowSnapshot>;
7083 memset(snap as ptr<u8>, 0, sizeof(CowSnapshot) as u64);
7084 (*snap).snap_id = cow_next_snap_id;
7085 cow_next_snap_id = cow_next_snap_id + 1;
7086 (*snap).timestamp = current_time_tick;
7087
7088 let mut curr_block = global_cow_mapping;
7089 while curr_block != 0 as ptr<CowBlock> {
7090 (*curr_block).ref_count = (*curr_block).ref_count + 1;
7091
7092 let copy_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
7093 memcpy(copy_node as ptr<u8>, curr_block as ptr<u8>, sizeof(CowBlock) as u64);
7094 (*copy_node).next = (*snap).blocks;
7095 (*snap).blocks = copy_node;
7096
7097 curr_block = (*curr_block).next;
7098 }
7099
7100 (*snap).next = global_snapshots;
7101 global_snapshots = snap;
7102 return (*snap).snap_id;
7103 }
7104
7105 fn cow_rollback_snapshot(snap_id: u32) -> bool {
7106 let mut snap = global_snapshots;
7107 while snap != 0 as ptr<CowSnapshot> {
7108 if (*snap).snap_id == snap_id {
7109 let mut old_mapping = global_cow_mapping;
7110 while old_mapping != 0 as ptr<CowBlock> {
7111 let next = (*old_mapping).next;
7112 pmm_free_blocks(old_mapping as u64, 1);
7113 old_mapping = next;
7114 }
7115
7116 global_cow_mapping = 0 as ptr<CowBlock>;
7117 let mut snap_block = (*snap).blocks;
7118 while snap_block != 0 as ptr<CowBlock> {
7119 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
7120 memcpy(new_node as ptr<u8>, snap_block as ptr<u8>, sizeof(CowBlock) as u64);
7121 (*new_node).next = global_cow_mapping;
7122 global_cow_mapping = new_node;
7123 snap_block = (*snap_block).next;
7124 }
7125 return true;
7126 }
7127 snap = (*snap).next;
7128 }
7129 return false;
7130 }
7131
7132 struct FacsHeader {
7133 signature: [u8; 4],
7134 length: u32,
7135 hardware_signature: u32,
7136 firmware_waking_vector: u32,
7137 global_lock: u32,
7138 flags: u32,
7139 x_firmware_waking_vector: u64,
7140 version: u8,
7141 reserved: [u8; 3],
7142 ospm_flags: u32,
7143 }
7144
7145 fn acpi_enter_s3_sleep() {
7146 if acpi_fadt == 0 as ptr<FADTHeader> { return; }
7147 let facs = (*acpi_fadt).firmware_ctrl as u64 as ptr<FacsHeader>;
7148
7149 (*facs).firmware_waking_vector = 0x8000;
7150
7151 let pm1a = (*acpi_fadt).pm1a_control_block;
7152 let pm1b = (*acpi_fadt).pm1b_control_block;
7153
7154 let slp_typ_a = 5;
7155 let slp_en = 1 << 13;
7156
7157 if pm1a != 0 { outw(pm1a as u16, (slp_typ_a << 10) | slp_en); }
7158 if pm1b != 0 { outw(pm1b as u16, (slp_typ_a << 10) | slp_en); }
7159
7160 cpu_cli();
7161 loop { cpu_hlt(); }
7162 }
7163
7164 struct TlsRecordHeader {
7165 content_type: u8,
7166 version_major: u8,
7167 version_minor: u8,
7168 length: u16,
7169 }
7170
7171 struct TlsHandshakeHeader {
7172 msg_type: u8,
7173 length: [u8; 3],
7174 }
7175
7176 const TLS_TYPE_CHANGE_CIPHER_SPEC: u8 = 20;
7177 const TLS_TYPE_ALERT: u8 = 21;
7178 const TLS_TYPE_HANDSHAKE: u8 = 22;
7179 const TLS_TYPE_APPLICATION_DATA: u8 = 23;
7180
7181 const TLS_HS_CLIENT_HELLO: u8 = 1;
7182 const TLS_HS_SERVER_HELLO: u8 = 2;
7183 const TLS_HS_CERTIFICATE: u8 = 11;
7184 const TLS_HS_SERVER_KEY_EXCHANGE: u8 = 12;
7185 const TLS_HS_SERVER_HELLO_DONE: u8 = 14;
7186 const TLS_HS_CLIENT_KEY_EXCHANGE: u8 = 16;
7187 const TLS_HS_FINISHED: u8 = 20;
7188
7189 struct TlsSession {
7190 sock: ptr<TcpSocket>,
7191 master_secret: [u8; 48],
7192 client_random: [u8; 32],
7193 server_random: [u8; 32],
7194 is_handshake_complete: bool,
7195 cipher_suite: u16,
7196 tx_sequence: u64,
7197 rx_sequence: u64,
7198 }
7199
7200 let mut global_tls_sessions: [TlsSession; 128];
7201 let mut tls_session_count: u32 = 0;
7202
7203 fn tls_init() {
7204 for i in 0..128 {
7205 global_tls_sessions[i].is_handshake_complete = false;
7206 global_tls_sessions[i].tx_sequence = 0;
7207 global_tls_sessions[i].rx_sequence = 0;
7208 }
7209 }
7210
7211 fn tls_send_client_hello(session: ptr<TlsSession>) {
7212 let buf = pmm_alloc_blocks(1) as ptr<u8>;
7213 let rec = buf as ptr<TlsRecordHeader>;
7214 (*rec).content_type = TLS_TYPE_HANDSHAKE;
7215 (*rec).version_major = 3;
7216 (*rec).version_minor = 3;
7217
7218 let hs = (buf as u64 + sizeof(TlsRecordHeader) as u64) as ptr<TlsHandshakeHeader>;
7219 (*hs).msg_type = TLS_HS_CLIENT_HELLO;
7220
7221 let hello_data = (buf as u64 + sizeof(TlsRecordHeader) as u64 + sizeof(TlsHandshakeHeader) as u64) as ptr<u8>;
7222 *(hello_data) = 3; *(hello_data as u64 + 1) as ptr<u8> = 3;
7223
7224 for i in 0..32 {
7225 (*session).client_random[i] = (rand_next() & 0xFF) as u8;
7226 *(hello_data as u64 + 2 + i as u64) as ptr<u8> = (*session).client_random[i];
7227 }
7228
7229 *(hello_data as u64 + 34) as ptr<u8> = 0;
7230
7231 *(hello_data as u64 + 35) as ptr<u16> = htons(4);
7232 *(hello_data as u64 + 37) as ptr<u16> = htons(0xC02F);
7233 *(hello_data as u64 + 39) as ptr<u16> = htons(0xC02B);
7234
7235 *(hello_data as u64 + 41) as ptr<u8> = 1;
7236 *(hello_data as u64 + 42) as ptr<u8> = 0;
7237
7238 let hs_len = 43;
7239 (*hs).length[0] = 0;
7240 (*hs).length[1] = (hs_len >> 8) as u8;
7241 (*hs).length[2] = (hs_len & 0xFF) as u8;
7242
7243 (*rec).length = htons(sizeof(TlsHandshakeHeader) as u16 + hs_len as u16);
7244
7245 tcp_send_data((*session).sock, buf, sizeof(TlsRecordHeader) as u32 + sizeof(TlsHandshakeHeader) as u32 + hs_len);
7246 pmm_free_blocks(buf as u64, 1);
7247 }
7248
7249 fn tls_connect(sock: ptr<TcpSocket>) -> ptr<TlsSession> {
7250 if tls_session_count >= 128 { return 0 as ptr<TlsSession>; }
7251 let session = &global_tls_sessions[tls_session_count as usize];
7252 tls_session_count = tls_session_count + 1;
7253
7254 (*session).sock = sock;
7255 (*session).is_handshake_complete = false;
7256 tls_send_client_hello(session);
7257
7258 return session;
7259 }
7260
7261 struct LivePatchHeader {
7262 magic: u32,
7263 patch_version: u32,
7264 num_funcs: u32,
7265 }
7266
7267 struct LivePatchFunc {
7268 old_addr: u64,
7269 new_addr: u64,
7270 size: u32,
7271 }
7272
7273 fn livepatch_apply(patch_data: ptr<u8>) -> bool {
7274 let hdr = patch_data as ptr<LivePatchHeader>;
7275 if (*hdr).magic != 0x4B4C5058 { return false; }
7276
7277 let funcs = (patch_data as u64 + sizeof(LivePatchHeader) as u64) as ptr<LivePatchFunc>;
7278
7279 cpu_cli();
7280
7281 let cr0 = rdmsr(0);
7282 asm { "mov rax, cr0\n and rax, 0xFFFEFFFF\n mov cr0, rax" }
7283
7284 for i in 0..(*hdr).num_funcs {
7285 let f = (funcs as u64 + i as u64 * sizeof(LivePatchFunc) as u64) as ptr<LivePatchFunc>;
7286 let target = (*f).old_addr as ptr<u8>;
7287 let dest = (*f).new_addr;
7288
7289 *target = 0xE9;
7290 let rel_offset = (dest as i64 - ((*f).old_addr as i64 + 5)) as i32;
7291 *((target as u64 + 1) as ptr<i32>) = rel_offset;
7292 }
7293
7294 asm { "mov rax, cr0\n or rax, 0x00010000\n mov cr0, rax" }
7295
7296 cpu_sti();
7297 return true;
7298 }
7299
7300 fn rsod_dump_registers(ctx: ptr<CpuContext>) {
7301 comp_draw_rect(comp_root_window, 0, 0, comp_width, comp_height, 0xAA0000);
7302
7303 let mut y = 50;
7304 (*global_shell).win = comp_root_window;
7305 (*global_shell).fg_color = 0xFFFFFF;
7306
7307 shell_print_string("====================================================\n" as ptr<u8>);
7308 shell_print_string(" AEGIS-X KERNEL PANIC - RED SCREEN OF DEATH \n" as ptr<u8>);
7309 shell_print_string("====================================================\n" as ptr<u8>);
7310 shell_print_string("A critical system error has occurred. System halted.\n\n" as ptr<u8>);
7311
7312 let mut buf: [u8; 32];
7313 shell_print_string("RIP: 0x" as ptr<u8>); itoa((*ctx).rip as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7314 shell_print_string("RAX: 0x" as ptr<u8>); itoa((*ctx).rax as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
7315 shell_print_string("RBX: 0x" as ptr<u8>); itoa((*ctx).rbx as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7316 shell_print_string("RCX: 0x" as ptr<u8>); itoa((*ctx).rcx as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
7317 shell_print_string("RDX: 0x" as ptr<u8>); itoa((*ctx).rdx as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7318 shell_print_string("RSI: 0x" as ptr<u8>); itoa((*ctx).rsi as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
7319 shell_print_string("RDI: 0x" as ptr<u8>); itoa((*ctx).rdi as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7320 shell_print_string("RSP: 0x" as ptr<u8>); itoa((*ctx).rsp as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
7321 shell_print_string("RBP: 0x" as ptr<u8>); itoa((*ctx).rbp as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n\n" as ptr<u8>);
7322
7323 let cr2: u64; asm { "mov %0, cr2" out cr2 = cr2; }
7324 shell_print_string("CR2 (Fault Addr): 0x" as ptr<u8>); itoa(cr2 as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7325
7326 shell_print_string("\nStack Trace:\n" as ptr<u8>);
7327 let mut rbp_ptr = (*ctx).rbp as ptr<u64>;
7328 for i in 0..8 {
7329 if rbp_ptr as u64 == 0 { break; }
7330 let ret_addr = *(rbp_ptr as u64 + 8) as ptr<u64>;
7331 shell_print_string("[<0x" as ptr<u8>); itoa(*ret_addr as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(">]\n" as ptr<u8>);
7332 rbp_ptr = *rbp_ptr as ptr<u64>;
7333 }
7334
7335 shell_print_string("\nPlease restart your computer. (System Halted)" as ptr<u8>);
7336 }
7337
7338 fn kernel_panic(ctx: ptr<CpuContext>) -> ! {
7339 cpu_cli();
7340 rsod_dump_registers(ctx);
7341 loop { cpu_hlt(); }
7342 }
7343
7344 fn exc_page_fault(ctx: ptr<CpuContext>) {
7345 let cr2: u64; asm { "mov %0, cr2" out cr2 = cr2; }
7346 let err_code = (*ctx).r15;
7347
7348 let is_handled = false;
7349
7350 if !is_handled {
7351 kernel_panic(ctx);
7352 }
7353 }
7354
7355 fn syscall_handler_master() {
7356 let mut rax: u64; let mut rdi: u64; let mut rsi: u64;
7357 let mut rdx: u64; let mut r10: u64; let mut r8: u64; let mut r9: u64;
7358
7359 asm { "mov %0, rax" out rax = rax; }
7360 asm { "mov %0, rdi" out rdi = rdi; }
7361 asm { "mov %0, rsi" out rsi = rsi; }
7362 asm { "mov %0, rdx" out rdx = rdx; }
7363 asm { "mov %0, r10" out r10 = r10; }
7364 asm { "mov %0, r8" out r8 = r8; }
7365 asm { "mov %0, r9" out r9 = r9; }
7366
7367 if rax == 0 { asm { "mov rax, %0" in rax = sys_read_wrap(rdi, rsi, rdx); } }
7368 else if rax == 1 { asm { "mov rax, %0" in rax = sys_write_wrap(rdi, rsi, rdx); } }
7369 else if rax == 2 { asm { "mov rax, %0" in rax = sys_open_wrap(rdi, rsi); } }
7370 else if rax == 3 { pmm_free_blocks(rdi, 1); asm { "mov rax, 0" } }
7371 else if rax == 9 { asm { "mov rax, %0" in rax = sys_mmap(rdi, rsi, rdx, r10, r8, r9); } }
7372 else if rax == 59 { asm { "mov rax, %0" in rax = execve_ring3(rdi as ptr<u8>, rsi as u32, rdx as u32); } }
7373 else if rax == 60 { (*current_process).state = 0; scheduler_tick(); }
7374 else if rax == 100 { comp_draw_rect(rdi as ptr<CompositorWindow>, rsi as u32, rdx as u32, r10 as u32, r8 as u32, r9 as u32); asm { "mov rax, 0" } }
7375 else if rax == 101 { gui_draw_string(rdi as ptr<CompositorWindow>, rsi as ptr<u8>, rdx as u32, r10 as u32, r8 as u32, r9 as u32); asm { "mov rax, 0" } }
7376 else if rax == 200 { sha256_init(rdi as ptr<Sha256Ctx>); sha256_transform(rdi as ptr<Sha256Ctx>, rsi as ptr<u8>); asm { "mov rax, 0" } }
7377 else if rax == 300 { asm { "mov rax, %0" in rax = ipc_send_message(rdi, rsi, rdx as u32, r10 as ptr<u8>, r8 as u32) as u64; } }
7378 else if rax == 301 { asm { "mov rax, %0" in rax = ipc_receive_message(rdi, rsi as ptr<IpcMessage>) as u64; } }
7379 else if rax == 400 { asm { "mov rax, %0" in rax = tcp_create_socket() as u64; } }
7380 else if rax == 401 { tcp_connect(rdi as ptr<TcpSocket>, *(rsi as ptr<Ipv4Addr>), rdx as u16); asm { "mov rax, 0" } }
7381 else if rax == 402 { tcp_send_data(rdi as ptr<TcpSocket>, rsi as ptr<u8>, rdx as u32); asm { "mov rax, 0" } }
7382 else if rax == 500 { asm { "mov rax, %0" in rax = shm_create(rdi as u32, rsi, rdx as u32, r10) as u64; } }
7383 else if rax == 501 { asm { "mov rax, %0" in rax = shm_attach(rdi, rsi, rdx) as u64; } }
7384 else if rax == 600 { asm { "mov rax, %0" in rax = ptrace_attach(rdi, rsi) as u64; } }
7385 else if rax == 700 { asm { "mov rax, %0" in rax = display_srv_create_surface(rdi) as u64; } }
7386 else if rax == 800 { asm { "mov rax, %0" in rax = tensor_create(rdi as u32, rsi as u32) as u64; } }
7387 else { asm { "mov rax, -1" } }
7388 }
7389
7390 const MULTIBOOT_MAGIC: u32 = 0x2BADB002;
7391
7392 struct MultibootInfo {
7393 flags: u32,
7394 mem_lower: u32,
7395 mem_upper: u32,
7396 boot_device: u32,
7397 cmdline: u32,
7398 mods_count: u32,
7399 mods_addr: u32,
7400 syms: [u32; 4],
7401 mmap_length: u32,
7402 mmap_addr: u32,
7403 drives_length: u32,
7404 drives_addr: u32,
7405 config_table: u32,
7406 boot_loader_name: u32,
7407 apm_table: u32,
7408 vbe_control_info: u32,
7409 vbe_mode_info: u32,
7410 vbe_mode: u16,
7411 vbe_interface_seg: u16,
7412 vbe_interface_off: u16,
7413 vbe_interface_len: u16,
7414 framebuffer_addr: u64,
7415 framebuffer_pitch: u32,
7416 framebuffer_width: u32,
7417 framebuffer_height: u32,
7418 framebuffer_bpp: u8,
7419 framebuffer_type: u8,
7420 }
7421
7422 #[no_mangle]
7423 pub fn kmain(magic: u32, mb_info: ptr<MultibootInfo>) -> ! {
7424 cpu_cli();
7425
7426 if magic != MULTIBOOT_MAGIC {
7427 loop { cpu_hlt(); }
7428 }
7429
7430 init_gdt_smp();
7431 init_idt_smp();
7432
7433 let total_mem_kb = (*mb_info).mem_lower + (*mb_info).mem_upper;
7434 pmm_init(total_mem_kb as u64);
7435
7436 vmm_init();
7437
7438 acpi_init();
7439
7440 smp_init_all();
7441 smp_balancer_init();
7442
7443 let w = (*mb_info).framebuffer_width;
7444 let h = (*mb_info).framebuffer_height;
7445 let fb_base = (*mb_info).framebuffer_addr;
7446 comp_init(fb_base, w, h);
7447 vt_init();
7448 render_init_3d(w, h);
7449
7450 pcie_init();
7451
7452 if global_ahci_hba != 0 as ptr<AHCIHBARegs> {
7453 raid_init_system();
7454 for i in 0..32 {
7455 let port = &((*global_ahci_hba).ports[i as usize]) as ptr<AHCIPortRegs>;
7456 if ((*port).ssts & 0x0F) == 3 {
7457 raid_add_disk(port, 100000000);
7458 }
7459 }
7460 }
7461
7462 vfs_init_system();
7463 if global_raid_sys.disk_count > 0 {
7464 ext2_init(0);
7465 jbd2_init(2000000, 2100000);
7466 }
7467 cow_init();
7468
7469 if (*mb_info).mods_count > 0 {
7470 let mod_addr = (*mb_info).mods_addr as ptr<u32>;
7471 let initramfs_start = *mod_addr;
7472 let initramfs_end = *(mod_addr as u64 + 4) as ptr<u32>;
7473 tar_extract_initramfs(initramfs_start as u64, (*initramfs_end - initramfs_start) as u64);
7474 }
7475
7476 loopback_init();
7477 fw_init();
7478 nat_init();
7479 tls_init();
7480
7481 auth_init_system();
7482 registry_init();
7483 db_init();
7484 av_init();
7485
7486 pmu_init();
7487 acpi_update_battery_state();
7488
7489 vmx_init();
7490
7491 let shell_pid = execve_ring3("/bin/aegis_shell" as ptr<u8>, 0, 0);
7492 if shell_pid == 0 {
7493 let proc = create_process(shell_task as u64, true);
7494 }
7495
7496 let http_proc = create_process(http_server_task as u64, true);
7497
7498 init_set_runlevel(3);
7499
7500 cpu_sti();
7501
7502 loop {
7503 scheduler_tick();
7504 smp_balance_load();
7505 display_srv_composite();
7506 usb_hub_poll_ports();
7507 cpu_pause();
7508 }
7509 }
7510
7511 struct YbgTransaction {
7512 sender_pubkey: [u8; 64],
7513 receiver_pubkey: [u8; 64],
7514 amount: u64,
7515 signature: [u8; 64],
7516 timestamp: u64,
7517 }
7518
7519 struct YbgBlockHeader {
7520 index: u64,
7521 prev_hash: [u8; 32],
7522 merkle_root: [u8; 32],
7523 timestamp: u64,
7524 difficulty: u32,
7525 nonce: u64,
7526 }
7527
7528 struct YbgBlock {
7529 header: YbgBlockHeader,
7530 transactions: ptr<YbgTransaction>,
7531 tx_count: u32,
7532 block_hash: [u8; 32],
7533 next: ptr<YbgBlock>,
7534 }
7535
7536 let mut blockchain_head: ptr<YbgBlock>;
7537 let mut current_difficulty: u32 = 4;
7538
7539 fn ybg_chain_init() {
7540 blockchain_head = pmm_alloc_blocks(1) as ptr<YbgBlock>;
7541 memset(blockchain_head as ptr<u8>, 0, sizeof(YbgBlock) as u64);
7542 (*blockchain_head).header.index = 0;
7543 strcpy(&((*blockchain_head).header.prev_hash[0]) as ptr<u8>, "YBG13_GENESIS_BLOCK_00000000000" as ptr<u8>);
7544 (*blockchain_head).header.timestamp = current_time_tick;
7545 (*blockchain_head).header.difficulty = current_difficulty;
7546 (*blockchain_head).header.nonce = 0;
7547 (*blockchain_head).tx_count = 0;
7548 }
7549
7550 fn ybg_check_hash_difficulty(hash: ptr<u8>, difficulty: u32) -> bool {
7551 let mut zero_count = 0;
7552 for i in 0..32 {
7553 let byte = *(hash as u64 + i as u64) as ptr<u8>;
7554 if *byte == 0 {
7555 zero_count = zero_count + 2;
7556 } else if (*byte & 0xF0) == 0 {
7557 zero_count = zero_count + 1;
7558 break;
7559 } else {
7560 break;
7561 }
7562 if zero_count >= difficulty { return true; }
7563 }
7564 return zero_count >= difficulty;
7565 }
7566
7567 fn ybg_mine_block(target_block: ptr<YbgBlock>) {
7568 let mut attempt_hash: [u8; 32];
7569 let mut ctx: Sha256Ctx;
7570
7571 shell_print_string("CHT-Miner: YBG13 Token kazimi basladi...\n" as ptr<u8>);
7572
7573 loop {
7574 sha256_init(&ctx);
7575 sha256_transform(&ctx, &((*target_block).header) as ptr<YbgBlockHeader> as ptr<u8>);
7576
7577 let state_ptr = &ctx.state[0] as ptr<u32> as ptr<u8>;
7578 for i in 0..32 { attempt_hash[i] = *(state_ptr + i); }
7579
7580 if ybg_check_hash_difficulty(&attempt_hash[0] as ptr<u8>, (*target_block).header.difficulty) {
7581 for i in 0..32 { (*target_block).block_hash[i] = attempt_hash[i]; }
7582 shell_print_string("CHT-Miner: Blok Bulundu! Nonce: " as ptr<u8>);
7583 let mut buf: [u8; 32]; itoa((*target_block).header.nonce as i32, 10, &buf[0] as ptr<u8>);
7584 shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7585 break;
7586 }
7587
7588 (*target_block).header.nonce = (*target_block).header.nonce + 1;
7589 if ((*target_block).header.nonce % 10000) == 0 { scheduler_tick(); }
7590 }
7591 }
7592
7593 struct ChtScanTarget {
7594 ip: Ipv4Addr,
7595 port_start: u16,
7596 port_end: u16,
7597 open_ports: [u16; 1024],
7598 open_count: u32,
7599 }
7600
7601 fn cht_stealth_syn_scan(target: ptr<ChtScanTarget>) {
7602 shell_print_string("CHT-Sec: Stealth SYN Scan baslatiliyor...\n" as ptr<u8>);
7603
7604 let sock = tcp_create_socket();
7605 if sock == 0 as ptr<TcpSocket> { return; }
7606
7607 (*target).open_count = 0;
7608
7609 for port in (*target).port_start..=(*target).port_end {
7610 tcp_bind(sock, 45000 + (port % 10000));
7611 (*sock).remote_ip = (*target).ip;
7612 (*sock).remote_port = port;
7613 (*sock).seq_num = hw_rdrand_64() as u32;
7614
7615 tcp_send_segment(sock, 0x0002, 0 as ptr<u8>, 0);
7616
7617 let mut timeout = 5000;
7618 let mut port_open = false;
7619
7620 while timeout > 0 {
7621 if (*sock).state == TCP_STATE_SYN_RCVD || (*sock).state == TCP_STATE_ESTABLISHED {
7622 port_open = true;
7623 break;
7624 }
7625 if (*sock).state == TCP_STATE_CLOSED { break; }
7626 timeout = timeout - 1;
7627 cpu_pause();
7628 }
7629
7630 if port_open {
7631 if (*target).open_count < 1024 {
7632 (*target).open_ports[(*target).open_count as usize] = port;
7633 (*target).open_count = (*target).open_count + 1;
7634
7635 shell_print_string("CHT-Sec: Port Acik -> " as ptr<u8>);
7636 let mut pbuf: [u8; 16]; itoa(port as i32, 10, &pbuf[0] as ptr<u8>);
7637 shell_print_string(&pbuf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7638 }
7639 tcp_send_segment(sock, 0x0004, 0 as ptr<u8>, 0);
7640 }
7641
7642 (*sock).state = TCP_STATE_CLOSED;
7643 (*sock).rx_head = 0; (*sock).rx_tail = 0;
7644 }
7645
7646 global_tcp_sockets[(*sock).id as usize - 1].is_active = false;
7647 shell_print_string("CHT-Sec: Tarama Tamamlandi.\n" as ptr<u8>);
7648 }
7649
7650 struct UavTelemetryPacket {
7651 magic: u32,
7652 device_id: u8,
7653 timestamp: u64,
7654 accel_x: f32,
7655 accel_y: f32,
7656 accel_z: f32,
7657 gyro_x: f32,
7658 gyro_y: f32,
7659 gyro_z: f32,
7660 depth_pressure: f32,
7661 motor_rpm: [u16; 4],
7662 battery_voltage: f32,
7663 checksum: u16,
7664 }
7665
7666 let mut uav_last_telemetry: UavTelemetryPacket;
7667
7668 fn uav_parse_telemetry(udp_payload: ptr<u8>, length: u32) {
7669 if length != sizeof(UavTelemetryPacket) as u32 { return; }
7670
7671 let pkt = udp_payload as ptr<UavTelemetryPacket>;
7672 if (*pkt).magic != 0x414E4B41 { return; } // 'ANKA'
7673
7674 let mut csum: u32 = 0;
7675 let ptr16 = udp_payload as ptr<u16>;
7676 for i in 0..((length - 2) / 2) {
7677 csum = csum + *(ptr16 as u64 + i as u64 * 2) as ptr<u16> as u32;
7678 }
7679 while (csum >> 16) != 0 { csum = (csum & 0xFFFF) + (csum >> 16); }
7680 let calc_csum = (!csum) as u16;
7681
7682 if calc_csum == (*pkt).checksum {
7683 memcpy(&uav_last_telemetry as ptr<UavTelemetryPacket> as ptr<u8>, udp_payload, length as u64);
7684 }
7685 }
7686
7687 const TK_EOF: u8 = 0;
7688 const TK_IDENTIFIER: u8 = 1;
7689 const TK_NUMBER: u8 = 2;
7690 const TK_PLUS: u8 = 3;
7691 const TK_MINUS: u8 = 4;
7692 const TK_ASSIGN: u8 = 5;
7693 const TK_PRINT: u8 = 6;
7694 const TK_SEMI: u8 = 7;
7695
7696 struct ScriptToken {
7697 type_: u8,
7698 value_int: i64,
7699 name: [u8; 32],
7700 }
7701
7702 struct ScriptLexer {
7703 src: ptr<u8>,
7704 pos: u32,
7705 len: u32,
7706 }
7707
7708 fn script_is_alpha(c: u8) -> bool { return (c >= 'a' as u8 && c <= 'z' as u8) || (c >= 'A' as u8 && c <= 'Z' as u8) || c == '_' as u8; }
7709 fn script_is_digit(c: u8) -> bool { return c >= '0' as u8 && c <= '9' as u8; }
7710
7711 fn script_next_token(lex: ptr<ScriptLexer>, out_tok: ptr<ScriptToken>) {
7712 while (*lex).pos < (*lex).len {
7713 let c = *((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>;
7714 if c == ' ' as u8 || c == 10 || c == 13 || c == 9 {
7715 (*lex).pos = (*lex).pos + 1;
7716 continue;
7717 }
7718
7719 if script_is_digit(c) {
7720 (*out_tok).type_ = TK_NUMBER;
7721 (*out_tok).value_int = 0;
7722 while (*lex).pos < (*lex).len && script_is_digit(*((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>) {
7723 (*out_tok).value_int = (*out_tok).value_int * 10 + (*((*lex).src as u64 + (*lex).pos as u64) as ptr<u8> - '0' as u8) as i64;
7724 (*lex).pos = (*lex).pos + 1;
7725 }
7726 return;
7727 }
7728
7729 if script_is_alpha(c) {
7730 let mut i = 0;
7731 while (*lex).pos < (*lex).len && (script_is_alpha(*((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>) || script_is_digit(*((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>)) && i < 31 {
7732 (*out_tok).name[i] = *((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>;
7733 (*lex).pos = (*lex).pos + 1;
7734 i = i + 1;
7735 }
7736 (*out_tok).name[i] = 0;
7737
7738 if strcmp(&((*out_tok).name[0]) as ptr<u8>, "print" as ptr<u8>) == 0 {
7739 (*out_tok).type_ = TK_PRINT;
7740 } else {
7741 (*out_tok).type_ = TK_IDENTIFIER;
7742 }
7743 return;
7744 }
7745
7746 if c == '+' as u8 { (*out_tok).type_ = TK_PLUS; (*lex).pos = (*lex).pos + 1; return; }
7747 if c == '-' as u8 { (*out_tok).type_ = TK_MINUS; (*lex).pos = (*lex).pos + 1; return; }
7748 if c == '=' as u8 { (*out_tok).type_ = TK_ASSIGN; (*lex).pos = (*lex).pos + 1; return; }
7749 if c == ';' as u8 { (*out_tok).type_ = TK_SEMI; (*lex).pos = (*lex).pos + 1; return; }
7750
7751 (*lex).pos = (*lex).pos + 1;
7752 }
7753 (*out_tok).type_ = TK_EOF;
7754 }
7755
7756 struct ScriptVar {
7757 name: [u8; 32],
7758 value: i64,
7759 is_active: bool,
7760 }
7761
7762 let mut global_script_env: [ScriptVar; 64];
7763
7764 fn script_set_var(name: ptr<u8>, val: i64) {
7765 for i in 0..64 {
7766 if global_script_env[i].is_active && strcmp(&(global_script_env[i].name[0]) as ptr<u8>, name) == 0 {
7767 global_script_env[i].value = val;
7768 return;
7769 }
7770 }
7771 for i in 0..64 {
7772 if !global_script_env[i].is_active {
7773 strcpy(&(global_script_env[i].name[0]) as ptr<u8>, name);
7774 global_script_env[i].value = val;
7775 global_script_env[i].is_active = true;
7776 return;
7777 }
7778 }
7779 }
7780
7781 fn script_get_var(name: ptr<u8>) -> i64 {
7782 for i in 0..64 {
7783 if global_script_env[i].is_active && strcmp(&(global_script_env[i].name[0]) as ptr<u8>, name) == 0 {
7784 return global_script_env[i].value;
7785 }
7786 }
7787 return 0;
7788 }
7789
7790 fn aegis_script_run(source_code: ptr<u8>) {
7791 let mut lex: ScriptLexer;
7792 lex.src = source_code;
7793 lex.pos = 0;
7794 lex.len = strlen(source_code) as u32;
7795
7796 for i in 0..64 { global_script_env[i].is_active = false; }
7797
7798 let mut tok: ScriptToken;
7799 script_next_token(&mut lex, &mut tok);
7800
7801 while tok.type_ != TK_EOF {
7802 if tok.type_ == TK_IDENTIFIER {
7803 let var_name = tok.name;
7804 script_next_token(&mut lex, &mut tok);
7805 if tok.type_ == TK_ASSIGN {
7806 script_next_token(&mut lex, &mut tok);
7807 let mut val: i64 = 0;
7808 if tok.type_ == TK_NUMBER { val = tok.value_int; }
7809 else if tok.type_ == TK_IDENTIFIER { val = script_get_var(&tok.name[0] as ptr<u8>); }
7810 script_set_var(&var_name[0] as ptr<u8>, val);
7811 script_next_token(&mut lex, &mut tok);
7812 }
7813 } else if tok.type_ == TK_PRINT {
7814 script_next_token(&mut lex, &mut tok);
7815 let mut val: i64 = 0;
7816 if tok.type_ == TK_NUMBER { val = tok.value_int; }
7817 else if tok.type_ == TK_IDENTIFIER { val = script_get_var(&tok.name[0] as ptr<u8>); }
7818
7819 shell_print_string("Aegis-Script Out: " as ptr<u8>);
7820 let mut buf: [u8; 32]; itoa(val as i32, 10, &buf[0] as ptr<u8>);
7821 shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7822 script_next_token(&mut lex, &mut tok);
7823 } else {
7824 script_next_token(&mut lex, &mut tok);
7825 }
7826 }
7827 }
7828
7829 const MB_MAGIC: u32 = 0x1BADB002;
7830 const MB_FLAGS: u32 = 0x00000003;
7831 const MB_CKSUM: u32 = -(MB_MAGIC + MB_FLAGS);
7832 struct Multiboot { magic: u32, flags: u32, checksum: u32 }
7833 const HEADER: Multiboot = Multiboot { magic: MB_MAGIC, flags: MB_FLAGS, checksum: MB_CKSUM };
7834
7835 fn outb(p: u16, d: u8) { asm { "out dx, al" in dx = p; in al = d; } }
7836 fn outw(p: u16, d: u16) { asm { "out dx, ax" in dx = p; in ax = d; } }
7837 fn outl(p: u16, d: u32) { asm { "out dx, eax" in dx = p; in eax = d; } }
7838 fn inb(p: u16) -> u8 { let mut d: u8; asm { "in al, dx" in dx = p; out al = d; } return d; }
7839 fn inw(p: u16) -> u16 { let mut d: u16; asm { "in ax, dx" in dx = p; out ax = d; } return d; }
7840 fn inl(p: u16) -> u32 { let mut d: u32; asm { "in eax, dx" in dx = p; out eax = d; } return d; }
7841
7842 struct CpuContext {
7843 r15: u64, r14: u64, r13: u64, r12: u64,
7844 r11: u64, r10: u64, r9: u64, r8: u64,
7845 rbp: u64, rdi: u64, rsi: u64, rdx: u64,
7846 rcx: u64, rbx: u64, rax: u64,
7847 rip: u64, cs: u64, rflags: u64, rsp: u64, ss: u64,
7848 }
7849
7850 struct ProcessControlBlock {
7851 pid: u64,
7852 state: u8,
7853 cr3_phys: u64,
7854 context: ptr<CpuContext>,
7855 time_slice: u64,
7856 privilege_level: u8,
7857 next: ptr<ProcessControlBlock>,
7858 }
7859
7860 let mut current_process: ptr<ProcessControlBlock> = 0 as ptr<ProcessControlBlock>;
7861 let mut process_queue: ptr<ProcessControlBlock> = 0 as ptr<ProcessControlBlock>;
7862
7863 fn sched() {
7864 if current_process == 0 as ptr<ProcessControlBlock> { return; }
7865 let mut next_proc = (*current_process).next;
7866 if next_proc == 0 as ptr<ProcessControlBlock> {
7867 next_proc = process_queue;
7868 }
7869 while (*next_proc).state != 1 {
7870 next_proc = (*next_proc).next;
7871 if next_proc == 0 as ptr<ProcessControlBlock> { next_proc = process_queue; }
7872 }
7873 current_process = next_proc;
7874 }
7875
7876 struct AegisCap {
7877 uid: u32,
7878 net_access: bool,
7879 fs_access: bool,
7880 hw_access: bool,
7881 }
7882
7883 fn aegis_verify(proc: ptr<ProcessControlBlock>, req_cap: u8) -> bool {
7884 if (*proc).privilege_level == 0 { return true; }
7885 return false;
7886 }
7887
7888 fn syscall_handler() {
7889 let mut eax: u32; let mut ebx: u32; let mut ecx: u32; let mut edx: u32;
7890 asm { "mov %0, eax" out eax = eax; }
7891 asm { "mov %0, ebx" out ebx = ebx; }
7892 asm { "mov %0, ecx" out ecx = ecx; }
7893 asm { "mov %0, edx" out edx = edx; }
7894
7895 if eax == 1 { asm { "mov eax, %0" in eax = kmalloc(ebx) as u32; } }
7896 else if eax == 2 { kfree(ebx as ptr<u8>); asm { "mov eax, 0" } }
7897 else if eax == 3 { wm_crt(ebx, ecx); asm { "mov eax, 0" } }
7898 else if eax == 4 { tcp_syn(0, ebx as u16, ecx as u16); asm { "mov eax, 0" } }
7899 else if eax == 5 { crypto_init(); asm { "mov eax, 0" } }
7900 else { asm { "mov eax, -1" } }
7901 }
7902
7903 fn idle_t() { loop { cpu_hlt(); sched(); } }
7904 fn gui_t() { loop { wm_cmp(); sched(); } }
7905 fn net_t() { loop { arp_req(0); sched(); } }
7906
7907 #[no_mangle]
7908 pub fn _start() -> ! {
7909 cpu_cli();
7910 init_gdt_smp();
7911 init_idt_smp();
7912 pmm_init();
7913 vmm_init();
7914 init_apic_smp();
7915
7916 crypto_init();
7917 vfs_init();
7918
7919 create_process(idle_t as u64, 0);
7920 create_process(gui_t as u64, 0);
7921 create_process(net_t as u64, 0);
7922
7923 cpu_sti();
7924 loop {
7925 sched();
7926 cpu_pause();
7927 }
7928 }
7929 const DRIVER_TYPE_NETWORK: u8 = 1;
7930 const DRIVER_TYPE_STORAGE: u8 = 2;
7931 const DRIVER_TYPE_DISPLAY: u8 = 3;
7932 const DRIVER_TYPE_AUDIO: u8 = 4;
7933 const DRIVER_TYPE_INPUT: u8 = 5;
7934 const DRIVER_TYPE_USB_HC: u8 = 6;
7935
7936 struct DeviceDriver {
7937 name: [u8; 32],
7938 drv_type: u8,
7939 init_func: u64,
7940 read_func: u64,
7941 write_func: u64,
7942 irq_handler: u64,
7943 is_loaded: bool,
7944 }
7945
7946 let mut global_driver_registry: [DeviceDriver; 1024];
7947 let mut registered_driver_count: u32 = 0;
7948
7949 fn register_driver(name: ptr<u8>, d_type: u8, init: u64, read: u64, write: u64, irq: u64) {
7950 if registered_driver_count >= 1024 { return; }
7951 let drv = &global_driver_registry[registered_driver_count as usize];
7952 strcpy(&(drv.name[0]) as ptr<u8>, name);
7953 drv.drv_type = d_type;
7954 drv.init_func = init;
7955 drv.read_func = read;
7956 drv.write_func = write;
7957 drv.irq_handler = irq;
7958 drv.is_loaded = false;
7959 registered_driver_count = registered_driver_count + 1;
7960 }
7961
7962
7963 fn drv_e1000_init() -> bool { shell_print_string("Loading Intel PRO/1000...\n" as ptr<u8>); return true; }
7964 fn drv_e1000e_init() -> bool { shell_print_string("Loading Intel PCIe Gigabit...\n" as ptr<u8>); return true; }
7965 fn drv_ixgbe_init() -> bool { shell_print_string("Loading Intel 10GbE...\n" as ptr<u8>); return true; }
7966 fn drv_rtl8139_init() -> bool { shell_print_string("Loading Realtek 8139...\n" as ptr<u8>); return true; }
7967 fn drv_rtl8168_init() -> bool { shell_print_string("Loading Realtek 8168/8111...\n" as ptr<u8>); return true; }
7968 fn drv_virtio_net_init() -> bool { shell_print_string("Loading VirtIO Network...\n" as ptr<u8>); return true; }
7969 fn drv_broadcom_net_init() -> bool { shell_print_string("Loading Broadcom NetXtreme...\n" as ptr<u8>); return true; }
7970 fn drv_atheros_wifi_init() -> bool { shell_print_string("Loading Atheros 802.11...\n" as ptr<u8>); return true; }
7971 fn drv_intel_wifi_init() -> bool { shell_print_string("Loading Intel Wireless WiFi...\n" as ptr<u8>); return true; }
7972
7973 fn drv_ahci_init() -> bool { shell_print_string("Loading AHCI SATA Controller...\n" as ptr<u8>); return true; }
7974 fn drv_nvme_init() -> bool { shell_print_string("Loading NVMe Controller...\n" as ptr<u8>); return true; }
7975 fn drv_ide_init() -> bool { shell_print_string("Loading Legacy IDE Controller...\n" as ptr<u8>); return true; }
7976 fn drv_virtio_blk_init() -> bool { shell_print_string("Loading VirtIO Block...\n" as ptr<u8>); return true; }
7977 fn drv_sdhci_init() -> bool { shell_print_string("Loading SD Host Controller...\n" as ptr<u8>); return true; }
7978 fn drv_lsi_sas_init() -> bool { shell_print_string("Loading LSI SAS Controller...\n" as ptr<u8>); return true; }
7979
7980
7981 fn drv_xhci_init() -> bool { shell_print_string("Loading USB 3.0 xHCI...\n" as ptr<u8>); return true; }
7982 fn drv_ehci_init() -> bool { shell_print_string("Loading USB 2.0 EHCI...\n" as ptr<u8>); return true; }
7983 fn drv_uhci_init() -> bool { shell_print_string("Loading USB 1.1 UHCI...\n" as ptr<u8>); return true; }
7984 fn drv_ohci_init() -> bool { shell_print_string("Loading USB 1.0 OHCI...\n" as ptr<u8>); return true; }
7985
7986
7987 fn drv_intel_gma_init() -> bool { shell_print_string("Loading Intel GMA/HD Graphics...\n" as ptr<u8>); return true; }
7988 fn drv_amd_radeon_init() -> bool { shell_print_string("Loading AMD Radeon Graphics...\n" as ptr<u8>); return true; }
7989 fn drv_nvidia_nouveau_init() -> bool { shell_print_string("Loading Nvidia (Nouveau) Graphics...\n" as ptr<u8>); return true; }
7990 fn drv_virtio_gpu_init() -> bool { shell_print_string("Loading VirtIO GPU...\n" as ptr<u8>); return true; }
7991 fn drv_vbox_video_init() -> bool { shell_print_string("Loading VirtualBox Video...\n" as ptr<u8>); return true; }
7992 fn drv_vmware_svga_init() -> bool { shell_print_string("Loading VMware SVGA II...\n" as ptr<u8>); return true; }
7993 fn drv_bochs_vbe_init() -> bool { shell_print_string("Loading Bochs VBE Display...\n" as ptr<u8>); return true; }
7994 fn drv_intel_hda_init() -> bool { shell_print_string("Loading Intel High Definition Audio...\n" as ptr<u8>); return true; }
7995 fn drv_ac97_init() -> bool { shell_print_string("Loading AC97 Audio...\n" as ptr<u8>); return true; }
7996 fn drv_sb16_init() -> bool { shell_print_string("Loading Sound Blaster 16...\n" as ptr<u8>); return true; }
7997 fn drv_ps2_kbd_init() -> bool { shell_print_string("Loading PS/2 Keyboard...\n" as ptr<u8>); return true; }
7998 fn drv_ps2_mouse_init() -> bool { shell_print_string("Loading PS/2 Mouse...\n" as ptr<u8>); return true; }
7999 fn drv_usb_hid_init() -> bool { shell_print_string("Loading USB HID (Kbd/Mouse)...\n" as ptr<u8>); return true; }
8000 fn drv_i2c_hid_init() -> bool { shell_print_string("Loading I2C HID Touchpad...\n" as ptr<u8>); return true; }
8001 fn uda_register_all_drivers() {
8002 register_driver("e1000" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_e1000_init as u64, 0, 0, 0);
8003 register_driver("e1000e" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_e1000e_init as u64, 0, 0, 0);
8004 register_driver("ixgbe" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_ixgbe_init as u64, 0, 0, 0);
8005 register_driver("rtl8139" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_rtl8139_init as u64, 0, 0, 0);
8006 register_driver("rtl8168" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_rtl8168_init as u64, 0, 0, 0);
8007 register_driver("virtio-net" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_virtio_net_init as u64, 0, 0, 0);
8008 register_driver("bcm-net" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_broadcom_net_init as u64, 0, 0, 0);
8009 register_driver("ath-wifi" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_atheros_wifi_init as u64, 0, 0, 0);
8010 register_driver("iwlwifi" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_intel_wifi_init as u64, 0, 0, 0);
8011
8012 register_driver("ahci" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_ahci_init as u64, 0, 0, 0);
8013 register_driver("nvme" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_nvme_init as u64, 0, 0, 0);
8014 register_driver("ide" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_ide_init as u64, 0, 0, 0);
8015 register_driver("virtio-blk" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_virtio_blk_init as u64, 0, 0, 0);
8016 register_driver("sdhci" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_sdhci_init as u64, 0, 0, 0);
8017 register_driver("lsi-sas" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_lsi_sas_init as u64, 0, 0, 0);
8018
8019 register_driver("xhci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_xhci_init as u64, 0, 0, 0);
8020 register_driver("ehci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_ehci_init as u64, 0, 0, 0);
8021 register_driver("uhci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_uhci_init as u64, 0, 0, 0);
8022 register_driver("ohci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_ohci_init as u64, 0, 0, 0);
8023
8024 register_driver("intel-gma" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_intel_gma_init as u64, 0, 0, 0);
8025 register_driver("amd-radeon" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_amd_radeon_init as u64, 0, 0, 0);
8026 register_driver("nvidia" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_nvidia_nouveau_init as u64, 0, 0, 0);
8027 register_driver("virtio-gpu" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_virtio_gpu_init as u64, 0, 0, 0);
8028 register_driver("vbox-video" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_vbox_video_init as u64, 0, 0, 0);
8029 register_driver("vmware-svga" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_vmware_svga_init as u64, 0, 0, 0);
8030 register_driver("bochs-vbe" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_bochs_vbe_init as u64, 0, 0, 0);
8031
8032 register_driver("intel-hda" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_intel_hda_init as u64, 0, 0, 0);
8033 register_driver("ac97" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_ac97_init as u64, 0, 0, 0);
8034 register_driver("sb16" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_sb16_init as u64, 0, 0, 0);
8035
8036 register_driver("ps2-kbd" as ptr<u8>, DRIVER_TYPE_INPUT, drv_ps2_kbd_init as u64, 0, 0, 0);
8037 register_driver("ps2-mouse" as ptr<u8>, DRIVER_TYPE_INPUT, drv_ps2_mouse_init as u64, 0, 0, 0);
8038 register_driver("usb-hid" as ptr<u8>, DRIVER_TYPE_INPUT, drv_usb_hid_init as u64, 0, 0, 0);
8039 register_driver("i2c-hid" as ptr<u8>, DRIVER_TYPE_INPUT, drv_i2c_hid_init as u64, 0, 0, 0);
8040 }
8041
8042
8043 fn get_pci_vendor_name(vendor_id: u16) -> ptr<u8> {
8044 if vendor_id == 0x8086 { return "Intel Corporation" as ptr<u8>; }
8045 if vendor_id == 0x1002 { return "Advanced Micro Devices (AMD)" as ptr<u8>; }
8046 if vendor_id == 0x10DE { return "NVIDIA Corporation" as ptr<u8>; }
8047 if vendor_id == 0x10EC { return "Realtek Semiconductor Co., Ltd." as ptr<u8>; }
8048 if vendor_id == 0x14E4 { return "Broadcom Inc. and subsidiaries" as ptr<u8>; }
8049 if vendor_id == 0x1AF4 { return "Red Hat, Inc. (Virtio)" as ptr<u8>; }
8050 if vendor_id == 0x15AD { return "VMware" as ptr<u8>; }
8051 if vendor_id == 0x80EE { return "InnoTek Systemberatung GmbH (VirtualBox)" as ptr<u8>; }
8052 if vendor_id == 0x1022 { return "AMD (Legacy)" as ptr<u8>; }
8053 if vendor_id == 0x104C { return "Texas Instruments" as ptr<u8>; }
8054 if vendor_id == 0x11AB { return "Marvell Technology Group Ltd." as ptr<u8>; }
8055 if vendor_id == 0x197B { return "JMicron Technology Corp." as ptr<u8>; }
8056 if vendor_id == 0x1014 { return "IBM" as ptr<u8>; }
8057 if vendor_id == 0x0E11 { return "Compaq Computer Corporation" as ptr<u8>; }
8058 if vendor_id == 0x103C { return "Hewlett-Packard Company" as ptr<u8>; }
8059 if vendor_id == 0x1028 { return "Dell" as ptr<u8>; }
8060 if vendor_id == 0x1043 { return "ASUSTeK Computer Inc." as ptr<u8>; }
8061 if vendor_id == 0x1458 { return "Gigabyte Technology Co., Ltd" as ptr<u8>; }
8062 if vendor_id == 0x1462 { return "Micro-Star International Co., Ltd. [MSI]" as ptr<u8>; }
8063 if vendor_id == 0x15B3 { return "Mellanox Technologies" as ptr<u8>; }
8064 if vendor_id == 0x1B36 { return "Red Hat, Inc. (QEMU)" as ptr<u8>; }
8065 if vendor_id == 0x1C58 { return "HGST, Inc." as ptr<u8>; }
8066 if vendor_id == 0x144D { return "Samsung Electronics Co Ltd" as ptr<u8>; }
8067 if vendor_id == 0x152D { return "JMicron Technology Corp. (NVMe)" as ptr<u8>; }
8068 if vendor_id == 0x1D0F { return "Amazon.com, Inc." as ptr<u8>; }
8069 if vendor_id == 0x1AE0 { return "Google, Inc." as ptr<u8>; }
8070 if vendor_id == 0x106B { return "Apple Inc." as ptr<u8>; }
8071 if vendor_id == 0x105A { return "Promise Technology, Inc." as ptr<u8>; }
8072 if vendor_id == 0x10B5 { return "PLX Technology, Inc." as ptr<u8>; }
8073 if vendor_id == 0x10DF { return "Emulex Corporation" as ptr<u8>; }
8074 if vendor_id == 0x1106 { return "VIA Technologies, Inc." as ptr<u8>; }
8075 if vendor_id == 0x1179 { return "Toshiba Corporation" as ptr<u8>; }
8076 if vendor_id == 0x1186 { return "D-Link System Inc" as ptr<u8>; }
8077 if vendor_id == 0x13F0 { return "Sundance Technology Inc / IC Plus Corp" as ptr<u8>; }
8078 if vendor_id == 0x168C { return "Qualcomm Atheros" as ptr<u8>; }
8079 if vendor_id == 0x1814 { return "Ralink corp." as ptr<u8>; }
8080 if vendor_id == 0x1B21 { return "ASMedia Technology Inc." as ptr<u8>; }
8081 if vendor_id == 0x8087 { return "Intel Corporation (Wireless)" as ptr<u8>; }
8082 return "Unknown Vendor" as ptr<u8>;
8083 }
8084
8085 fn get_pci_device_name(vendor_id: u16, device_id: u16) -> ptr<u8> {
8086 // --- INTEL DEVICES ---
8087 if vendor_id == 0x8086 {
8088 if device_id == 0x100E { return "Gigabit Ethernet Controller (e1000)" as ptr<u8>; }
8089 if device_id == 0x100F { return "Gigabit Ethernet Controller (e1000)" as ptr<u8>; }
8090 if device_id == 0x10D3 { return "82574L Gigabit Network Connection" as ptr<u8>; }
8091 if device_id == 0x10EA { return "82577LM Gigabit Network Connection" as ptr<u8>; }
8092 if device_id == 0x1502 { return "82579LM Gigabit Network Connection" as ptr<u8>; }
8093 if device_id == 0x1503 { return "82579V Gigabit Network Connection" as ptr<u8>; }
8094 if device_id == 0x153A { return "I217-LM Gigabit Network Connection" as ptr<u8>; }
8095 if device_id == 0x153B { return "I217-V Gigabit Network Connection" as ptr<u8>; }
8096 if device_id == 0x15B7 { return "I219-LM Gigabit Network Connection" as ptr<u8>; }
8097 if device_id == 0x15B8 { return "I219-V Gigabit Network Connection" as ptr<u8>; }
8098 if device_id == 0x10FB { return "82599ES 10-Gigabit SFI/SFP+ Network Connection" as ptr<u8>; }
8099 if device_id == 0x1528 { return "Ethernet Controller 10-Gigabit X540-AT2" as ptr<u8>; }
8100 if device_id == 0x2922 { return "82801IR/IO/P (ICH9) 6 port SATA Controller [AHCI mode]" as ptr<u8>; }
8101 if device_id == 0x1C02 { return "6 Series/C200 Series Chipset Family 6 port SATA AHCI" as ptr<u8>; }
8102 if device_id == 0x1E02 { return "7 Series/C210 Series Chipset Family 6-port SATA Controller" as ptr<u8>; }
8103 if device_id == 0x8C02 { return "8 Series/C220 Series Chipset Family 6-port SATA Controller" as ptr<u8>; }
8104 if device_id == 0xA102 { return "100 Series/C230 Series Chipset Family SATA AHCI" as ptr<u8>; }
8105 if device_id == 0xA282 { return "200 Series/Z370 Chipset Family SATA AHCI Controller" as ptr<u8>; }
8106 if device_id == 0x0116 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
8107 if device_id == 0x0166 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
8108 if device_id == 0x0412 { return "4th Gen Core Processor Integrated Graphics Controller" as ptr<u8>; }
8109 if device_id == 0x1912 { return "HD Graphics 530" as ptr<u8>; }
8110 if device_id == 0x3E92 { return "UHD Graphics 630 (Desktop)" as ptr<u8>; }
8111 if device_id == 0x9BC5 { return "CometLake-S GT2 [UHD Graphics 630]" as ptr<u8>; }
8112 if device_id == 0x2668 { return "82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio" as ptr<u8>; }
8113 if device_id == 0x284B { return "82801H (ICH8 Family) High Definition Audio Controller" as ptr<u8>; }
8114 if device_id == 0x293E { return "82801I (ICH9 Family) High Definition Audio Controller" as ptr<u8>; }
8115 if device_id == 0x1E20 { return "7 Series/C210 Series Chipset Family High Definition Audio" as ptr<u8>; }
8116 if device_id == 0xA170 { return "100 Series/C230 Series Chipset Family HD Audio Controller" as ptr<u8>; }
8117 if device_id == 0x8C31 { return "8 Series/C220 Series Chipset Family USB xHCI" as ptr<u8>; }
8118 if device_id == 0xA12F { return "100 Series/C230 Series Chipset Family USB 3.0 xHCI" as ptr<u8>; }
8119 if device_id == 0x1E2D { return "7 Series/C210 Series Chipset Family USB Enhanced Host Controller" as ptr<u8>; }
8120 if device_id == 0x24C2 { return "82801DB/DBM (ICH4/ICH4-M) USB UHCI Controller" as ptr<u8>; }
8121 if device_id == 0xF1A5 { return "NVMe SSD Controller (Optane/760p)" as ptr<u8>; }
8122 if device_id == 0x4220 { return "PRO/Wireless 2200BG [Calexico2] Network Connection" as ptr<u8>; }
8123 if device_id == 0x4229 { return "PRO/Wireless 4965 AG or AGN [Kedron] Network Connection" as ptr<u8>; }
8124 if device_id == 0x0085 { return "Centrino Advanced-N 6205 [Taylor Peak]" as ptr<u8>; }
8125 if device_id == 0x08B1 { return "Wireless 7260" as ptr<u8>; }
8126 if device_id == 0x24FB { return "Dual Band Wireless-AC 3160" as ptr<u8>; }
8127 if device_id == 0x24FD { return "Dual Band Wireless-AC 8265" as ptr<u8>; }
8128 if device_id == 0x2723 { return "Wi-Fi 6 AX200" as ptr<u8>; }
8129 return "Intel Unknown Device" as ptr<u8>;
8130 }
8131
8132 // --- REALTEK DEVICES ---
8133 if vendor_id == 0x10EC {
8134 if device_id == 0x8139 { return "RTL-8100/8101L/8139 PCI Fast Ethernet Adapter" as ptr<u8>; }
8135 if device_id == 0x8168 { return "RTL8111/8168/8411 PCI Express Gigabit Ethernet" as ptr<u8>; }
8136 if device_id == 0x8169 { return "RTL8169 PCI Gigabit Ethernet Controller" as ptr<u8>; }
8137 if device_id == 0x8125 { return "RTL8125 2.5GbE Controller" as ptr<u8>; }
8138 if device_id == 0x818B { return "RTL8192EE PCIe Wireless Network Adapter" as ptr<u8>; }
8139 if device_id == 0x8821 { return "RTL8821AE 802.11ac PCIe Wireless Network Adapter" as ptr<u8>; }
8140 if device_id == 0x8822 { return "RTL8822BE 802.11a/b/g/n/ac WiFi adapter" as ptr<u8>; }
8141 if device_id == 0x522A { return "RTS522A PCI Express Card Reader" as ptr<u8>; }
8142 if device_id == 0x0282 { return "RTL8188EE Wireless Network Adapter" as ptr<u8>; }
8143 return "Realtek Unknown Device" as ptr<u8>;
8144 }
8145
8146 // --- NVIDIA DEVICES ---
8147 if vendor_id == 0x10DE {
8148 if device_id == 0x0402 { return "GeForce 8600 GT" as ptr<u8>; }
8149 if device_id == 0x0611 { return "GeForce 8800 GT" as ptr<u8>; }
8150 if device_id == 0x0A20 { return "GeForce GT 220" as ptr<u8>; }
8151 if device_id == 0x06C0 { return "GeForce GTX 480" as ptr<u8>; }
8152 if device_id == 0x1080 { return "GeForce GTX 580" as ptr<u8>; }
8153 if device_id == 0x1180 { return "GeForce GTX 680" as ptr<u8>; }
8154 if device_id == 0x13C2 { return "GeForce GTX 970" as ptr<u8>; }
8155 if device_id == 0x13C0 { return "GeForce GTX 980" as ptr<u8>; }
8156 if device_id == 0x1C03 { return "GeForce GTX 1060 6GB" as ptr<u8>; }
8157 if device_id == 0x1B81 { return "GeForce GTX 1070" as ptr<u8>; }
8158 if device_id == 0x1B06 { return "GeForce GTX 1080 Ti" as ptr<u8>; }
8159 if device_id == 0x1E84 { return "GeForce RTX 2070" as ptr<u8>; }
8160 if device_id == 0x1E07 { return "GeForce RTX 2080 Ti" as ptr<u8>; }
8161 if device_id == 0x2204 { return "GeForce RTX 3090" as ptr<u8>; }
8162 if device_id == 0x2484 { return "GeForce RTX 3070" as ptr<u8>; }
8163 if device_id == 0x2684 { return "GeForce RTX 4090" as ptr<u8>; }
8164 if device_id == 0x28E0 { return "GeForce RTX 4050 Laptop GPU" as ptr<u8>; } // YBG13's PC!
8165 if device_id == 0x0E0A { return "GF119 HDMI Audio Controller" as ptr<u8>; }
8166 if device_id == 0x0FB0 { return "GM200 High Definition Audio" as ptr<u8>; }
8167 if device_id == 0x10F0 { return "GP104 High Definition Audio Controller" as ptr<u8>; }
8168 if device_id == 0x10FA { return "TU104 HD Audio Controller" as ptr<u8>; }
8169 return "NVIDIA Unknown Device" as ptr<u8>;
8170 }
8171
8172 // --- AMD/ATI DEVICES ---
8173 if vendor_id == 0x1002 {
8174 if device_id == 0x6738 { return "Radeon HD 6870" as ptr<u8>; }
8175 if device_id == 0x6798 { return "Radeon HD 7970 / R9 280X" as ptr<u8>; }
8176 if device_id == 0x67B1 { return "Radeon R9 290 / 390" as ptr<u8>; }
8177 if device_id == 0x67DF { return "Radeon RX 470/480/570/580/590" as ptr<u8>; }
8178 if device_id == 0x687F { return "Radeon RX Vega 56/64" as ptr<u8>; }
8179 if device_id == 0x731F { return "Radeon RX 5700 XT" as ptr<u8>; }
8180 if device_id == 0x73BF { return "Radeon RX 6800 XT / 6900 XT" as ptr<u8>; }
8181 if device_id == 0x744C { return "Radeon RX 7900 XTX" as ptr<u8>; }
8182 if device_id == 0x4383 { return "SB7x0/SB8x0/SB9x0 High Definition Audio Controller" as ptr<u8>; }
8183 if device_id == 0x1457 { return "Family 17h (Models 00h-0fh) HD Audio Controller" as ptr<u8>; }
8184 if device_id == 0x4391 { return "SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode]" as ptr<u8>; }
8185 if device_id == 0x7901 { return "FCH SATA Controller [AHCI mode]" as ptr<u8>; }
8186 return "AMD/ATI Unknown Device" as ptr<u8>;
8187 }
8188
8189 // --- VIRTUALIZATION DEVICES (VIRTIO, VMWARE, VBOX) ---
8190 if vendor_id == 0x1AF4 {
8191 if device_id == 0x1000 { return "VirtIO Network Device" as ptr<u8>; }
8192 if device_id == 0x1001 { return "VirtIO Block Device" as ptr<u8>; }
8193 if device_id == 0x1002 { return "VirtIO Memory Balloon" as ptr<u8>; }
8194 if device_id == 0x1003 { return "VirtIO Console" as ptr<u8>; }
8195 if device_id == 0x1004 { return "VirtIO SCSI" as ptr<u8>; }
8196 if device_id == 0x1005 { return "VirtIO RNG" as ptr<u8>; }
8197 if device_id == 0x1041 { return "VirtIO Network Device (Modern)" as ptr<u8>; }
8198 if device_id == 0x1042 { return "VirtIO Block Device (Modern)" as ptr<u8>; }
8199 if device_id == 0x1050 { return "VirtIO GPU" as ptr<u8>; }
8200 return "VirtIO Unknown Device" as ptr<u8>;
8201 }
8202 if vendor_id == 0x15AD {
8203 if device_id == 0x0405 { return "VMware SVGA II Adapter" as ptr<u8>; }
8204 if device_id == 0x07B0 { return "VMware VMXNET3 Ethernet Controller" as ptr<u8>; }
8205 if device_id == 0x07A0 { return "VMware PVSCSI SCSI Controller" as ptr<u8>; }
8206 return "VMware Unknown Device" as ptr<u8>;
8207 }
8208 if vendor_id == 0x80EE {
8209 if device_id == 0xBEEF { return "VirtualBox Graphics Adapter" as ptr<u8>; }
8210 if device_id == 0xCAFE { return "VirtualBox Guest Service" as ptr<u8>; }
8211 return "VirtualBox Unknown Device" as ptr<u8>;
8212 }
8213
8214 // --- STORAGE/SAMSUNG/BROADCOM AND OTHERS ---
8215 if vendor_id == 0x144D {
8216 if device_id == 0xA802 { return "Samsung SM951 NVMe" as ptr<u8>; }
8217 if device_id == 0xA804 { return "Samsung 960 EVO/PRO NVMe" as ptr<u8>; }
8218 if device_id == 0xA808 { return "Samsung 970 EVO/PRO NVMe" as ptr<u8>; }
8219 if device_id == 0xA80A { return "Samsung 980 PRO NVMe" as ptr<u8>; }
8220 if device_id == 0xA80C { return "Samsung 990 PRO NVMe" as ptr<u8>; }
8221 return "Samsung NVMe Unknown" as ptr<u8>;
8222 }
8223 if vendor_id == 0x14E4 {
8224 if device_id == 0x1659 { return "NetXtreme BCM5721 Gigabit Ethernet" as ptr<u8>; }
8225 if device_id == 0x1677 { return "NetXtreme BCM5751 Gigabit Ethernet" as ptr<u8>; }
8226 if device_id == 0x4311 { return "BCM4311 802.11b/g WLAN" as ptr<u8>; }
8227 if device_id == 0x4322 { return "BCM4322 802.11a/b/g/n Wireless LAN" as ptr<u8>; }
8228 if device_id == 0x4360 { return "BCM4360 802.11ac Wireless Network Adapter" as ptr<u8>; }
8229 return "Broadcom Unknown Device" as ptr<u8>;
8230 }
8231 if vendor_id == 0x168C {
8232 if device_id == 0x002B { return "AR9285 Wireless Network Adapter" as ptr<u8>; }
8233 if device_id == 0x002E { return "AR9287 Wireless Network Adapter" as ptr<u8>; }
8234 if device_id == 0x0032 { return "AR9485 Wireless Network Adapter" as ptr<u8>; }
8235 if device_id == 0x003C { return "QCA986x/988x 802.11ac Wireless Network Adapter" as ptr<u8>; }
8236 return "Atheros Unknown Device" as ptr<u8>;
8237 }
8238
8239 return "Generic Unknown PCI Device" as ptr<u8>;
8240 }
8241
8242 struct PciDeviceInfo {
8243 bus: u8,
8244 slot: u8,
8245 func: u8,
8246 vendor_id: u16,
8247 device_id: u16,
8248 class_code: u8,
8249 subclass: u8,
8250 prog_if: u8,
8251 irq: u8,
8252 bar0: u32,
8253 bar1: u32,
8254 bar2: u32,
8255 bar3: u32,
8256 bar4: u32,
8257 bar5: u32,
8258 is_active: bool,
8259 }
8260
8261 let mut pci_device_tree: [PciDeviceInfo; 256];
8262 let mut pci_device_count: u32 = 0;
8263
8264 fn pci_config_read_word(bus: u8, slot: u8, func: u8, offset: u8) -> u16 {
8265 let address: u32 = ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32 & 0xFC) | 0x80000000;
8266 outl(0xCF8, address);
8267 let tmp = inl(0xCFC);
8268 return ((tmp >> ((offset & 2) * 8)) & 0xFFFF) as u16;
8269 }
8270
8271 fn pci_config_read_dword(bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
8272 let address: u32 = ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32 & 0xFC) | 0x80000000;
8273 outl(0xCF8, address);
8274 return inl(0xCFC);
8275 }
8276
8277 fn uda_probe_pci_bus() {
8278 shell_print_string("UDA: Probing PCI/PCIe Busses...\n" as ptr<u8>);
8279 for bus in 0..=255 {
8280 for slot in 0..32 {
8281 let vendor_id = pci_config_read_word(bus as u8, slot as u8, 0, 0);
8282 if vendor_id != 0xFFFF {
8283 let device_id = pci_config_read_word(bus as u8, slot as u8, 0, 2);
8284 let class_subclass = pci_config_read_word(bus as u8, slot as u8, 0, 0x0A);
8285 let class_code = (class_subclass >> 8) as u8;
8286 let subclass = (class_subclass & 0xFF) as u8;
8287 let prog_if = (pci_config_read_word(bus as u8, slot as u8, 0, 0x08) >> 8) as u8;
8288
8289 if pci_device_count < 256 {
8290 let dev = &pci_device_tree[pci_device_count as usize];
8291 dev.bus = bus as u8;
8292 dev.slot = slot as u8;
8293 dev.func = 0;
8294 dev.vendor_id = vendor_id;
8295 dev.device_id = device_id;
8296 dev.class_code = class_code;
8297 dev.subclass = subclass;
8298 dev.prog_if = prog_if;
8299 dev.is_active = true;
8300
8301 dev.bar0 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x10);
8302 dev.bar1 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x14);
8303 dev.bar2 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x18);
8304 dev.bar3 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x1C);
8305 dev.bar4 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x20);
8306 dev.bar5 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x24);
8307 dev.irq = (pci_config_read_word(bus as u8, slot as u8, 0, 0x3C) & 0xFF) as u8;
8308
8309 pci_device_count = pci_device_count + 1;
8310
8311 uda_match_and_load_driver(dev);
8312 }
8313 }
8314 }
8315 }
8316 shell_print_string("UDA: PCI Scan Complete. Found devices: " as ptr<u8>);
8317 let mut buf: [u8; 16];
8318 itoa(pci_device_count as i32, 10, &buf[0] as ptr<u8>);
8319 shell_print_string(&buf[0] as ptr<u8>);
8320 shell_print_string("\n" as ptr<u8>);
8321 }
8322
8323 fn uda_match_and_load_driver(dev: ptr<PciDeviceInfo>) {
8324 let vid = (*dev).vendor_id;
8325 let did = (*dev).device_id;
8326 let cls = (*dev).class_code;
8327 let sub = (*dev).subclass;
8328 let p_if = (*dev).prog_if;
8329
8330 // --- Mass Storage Controllers ---
8331 if cls == 0x01 {
8332 if sub == 0x01 {
8333 drv_ide_init();
8334 } else if sub == 0x06 && p_if == 0x01 {
8335 drv_ahci_init();
8336 } else if sub == 0x08 && p_if == 0x02 {
8337 drv_nvme_init();
8338 }
8339 }
8340 else if cls == 0x02 {
8341 if sub == 0x00 { // Ethernet
8342 if vid == 0x8086 {
8343 if did == 0x100E || did == 0x100F { drv_e1000_init(); }
8344 else if did == 0x153A || did == 0x153B { drv_e1000e_init(); }
8345 else { drv_e1000e_init(); } // Generic fallback for intel network
8346 } else if vid == 0x10EC {
8347 if did == 0x8139 { drv_rtl8139_init(); }
8348 else if did == 0x8168 { drv_rtl8168_init(); }
8349 } else if vid == 0x1AF4 && did == 0x1000 {
8350 drv_virtio_net_init();
8351 }
8352 } else if sub == 0x80 { // Network controller (often WiFi)
8353 if vid == 0x8086 || vid == 0x8087 { drv_intel_wifi_init(); }
8354 else if vid == 0x168C { drv_atheros_wifi_init(); }
8355 }
8356 }
8357 else if cls == 0x03 {
8358 if vid == 0x8086 { drv_intel_gma_init(); }
8359 else if vid == 0x1002 { drv_amd_radeon_init(); }
8360 else if vid == 0x10DE { drv_nvidia_nouveau_init(); }
8361 else if vid == 0x15AD { drv_vmware_svga_init(); }
8362 else if vid == 0x80EE { drv_vbox_video_init(); }
8363 else if vid == 0x1AF4 { drv_virtio_gpu_init(); }
8364 else { drv_bochs_vbe_init(); }
8365 }
8366
8367 else if cls == 0x04 {
8368 if sub == 0x01 { drv_ac97_init(); }
8369 else if sub == 0x03 { drv_intel_hda_init(); }
8370 }
8371 else if cls == 0x0C && sub == 0x03 {
8372 if p_if == 0x00 { drv_uhci_init(); }
8373 else if p_if == 0x10 { drv_ohci_init(); }
8374 else if p_if == 0x20 { drv_ehci_init(); }
8375 else if p_if == 0x30 { drv_xhci_init(); }
8376 }
8377 }
8378
8379 fn uda_dump_device_tree() {
8380 shell_print_string("\n--- UDA DEVICE TREE DUMP ---\n" as ptr<u8>);
8381 for i in 0..pci_device_count {
8382 let dev = &pci_device_tree[i as usize];
8383 let v_name = get_pci_vendor_name(dev.vendor_id);
8384 let d_name = get_pci_device_name(dev.vendor_id, dev.device_id);
8385
8386 shell_print_string("BUS: " as ptr<u8>);
8387 let mut bbuf: [u8; 8]; itoa(dev.bus as i32, 10, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
8388
8389 shell_print_string(" | VID: 0x" as ptr<u8>);
8390 itoa(dev.vendor_id as i32, 16, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
8391
8392 shell_print_string(" | DID: 0x" as ptr<u8>);
8393 itoa(dev.device_id as i32, 16, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
8394
8395 shell_print_string("\n -> " as ptr<u8>);
8396 shell_print_string(v_name); shell_print_string(" - " as ptr<u8>); shell_print_string(d_name);
8397 shell_print_string("\n" as ptr<u8>);
8398 }
8399 shell_print_string("----------------------------\n" as ptr<u8>);
8400 }
8401
8402 fn uda_thread() {
8403 uda_register_all_drivers();
8404 uda_probe_pci_bus();
8405 uda_dump_device_tree();
8406
8407 // UDA Daemon loop
8408 loop {
8409 // Here we would handle Hot-Plug events (PCIe Hotplug, USB Hotplug)
8410 cpu_pause();
8411 sched();
8412 }
8413 }
8414
8415 fn drv_lsi_megaraid_init() -> bool { shell_print_string("Loading LSI MegaRAID SAS...\n" as ptr<u8>); return true; }
8416 fn drv_adaptec_raid_init() -> bool { shell_print_string("Loading Adaptec AACRAID...\n" as ptr<u8>); return true; }
8417 fn drv_promise_fasttrak_init() -> bool { shell_print_string("Loading Promise FastTrak RAID...\n" as ptr<u8>); return true; }
8418 fn drv_highpoint_rocketraid_init() -> bool { shell_print_string("Loading HighPoint RocketRAID...\n" as ptr<u8>); return true; }
8419 fn drv_via_sata_init() -> bool { shell_print_string("Loading VIA SATA Controller...\n" as ptr<u8>); return true; }
8420 fn drv_sis_sata_init() -> bool { shell_print_string("Loading SiS SATA Controller...\n" as ptr<u8>); return true; }
8421 fn drv_uli_sata_init() -> bool { shell_print_string("Loading ULi SATA Controller...\n" as ptr<u8>); return true; }
8422 fn drv_marvell_sata_init() -> bool { shell_print_string("Loading Marvell 88SE SATA...\n" as ptr<u8>); return true; }
8423 fn drv_jmicron_sata_init() -> bool { shell_print_string("Loading JMicron JMB36x SATA...\n" as ptr<u8>); return true; }
8424 fn drv_asmedia_sata_init() -> bool { shell_print_string("Loading ASMedia ASM106x SATA...\n" as ptr<u8>); return true; }
8425 fn drv_mellanox_cx_init() -> bool { shell_print_string("Loading Mellanox ConnectX 10/40/100GbE...\n" as ptr<u8>); return true; }
8426 fn drv_3com_3c905_init() -> bool { shell_print_string("Loading 3Com 3c905B Fast EtherLink...\n" as ptr<u8>); return true; }
8427 fn drv_dec_tulip_init() -> bool { shell_print_string("Loading DEC Tulip Ethernet...\n" as ptr<u8>); return true; }
8428 fn drv_sis_900_init() -> bool { shell_print_string("Loading SiS 900 PCI Fast Ethernet...\n" as ptr<u8>); return true; }
8429 fn drv_via_rhine_init() -> bool { shell_print_string("Loading VIA Rhine II Fast Ethernet...\n" as ptr<u8>); return true; }
8430 fn drv_via_velocity_init() -> bool { shell_print_string("Loading VIA Velocity Gigabit...\n" as ptr<u8>); return true; }
8431 fn drv_marvell_yukon_init() -> bool { shell_print_string("Loading Marvell Yukon Gigabit...\n" as ptr<u8>); return true; }
8432 fn drv_broadcom_tg3_init() -> bool { shell_print_string("Loading Broadcom Tigon3 Gigabit...\n" as ptr<u8>); return true; }
8433 fn drv_intel_10gbe_vf_init() -> bool { shell_print_string("Loading Intel 10GbE Virtual Function...\n" as ptr<u8>); return true; }
8434 fn drv_solarflare_init() -> bool { shell_print_string("Loading Solarflare 10/40GbE...\n" as ptr<u8>); return true; }
8435 fn drv_qlogic_net_init() -> bool { shell_print_string("Loading QLogic 10/25GbE...\n" as ptr<u8>); return true; }
8436 fn drv_matrox_g400_init() -> bool { shell_print_string("Loading Matrox G400/G450/G550...\n" as ptr<u8>); return true; }
8437 fn drv_3dfx_voodoo_init() -> bool { shell_print_string("Loading 3dfx Voodoo Graphics...\n" as ptr<u8>); return true; }
8438 fn drv_cirrus_logic_init() -> bool { shell_print_string("Loading Cirrus Logic GD5446...\n" as ptr<u8>); return true; }
8439 fn drv_s3_trio_init() -> bool { shell_print_string("Loading S3 Trio32/64...\n" as ptr<u8>); return true; }
8440 fn drv_s3_savage_init() -> bool { shell_print_string("Loading S3 Savage 3D...\n" as ptr<u8>); return true; }
8441 fn drv_via_chrome_init() -> bool { shell_print_string("Loading VIA UniChrome Graphics...\n" as ptr<u8>); return true; }
8442 fn drv_creative_emu10k1_init() -> bool { shell_print_string("Loading Creative Sound Blaster Live!...\n" as ptr<u8>); return true; }
8443 fn drv_creative_xifi_init() -> bool { shell_print_string("Loading Creative X-Fi Audio...\n" as ptr<u8>); return true; }
8444 fn drv_via_envy24_init() -> bool { shell_print_string("Loading VIA Envy24 Audio...\n" as ptr<u8>); return true; }
8445 fn drv_cmedia_cmi8738_init() -> bool { shell_print_string("Loading C-Media CMI8738 Audio...\n" as ptr<u8>); return true; }
8446 fn drv_cmedia_oxygen_init() -> bool { shell_print_string("Loading C-Media Oxygen HD Audio...\n" as ptr<u8>); return true; }
8447 fn drv_ess_solo1_init() -> bool { shell_print_string("Loading ESS Solo-1 Audio...\n" as ptr<u8>); return true; }
8448 fn drv_yamaha_ymf724_init() -> bool { shell_print_string("Loading Yamaha YMF724 Audio...\n" as ptr<u8>); return true; }
8449 fn drv_fresco_logic_xhci_init() -> bool { shell_print_string("Loading Fresco Logic xHCI USB 3.0...\n" as ptr<u8>); return true; }
8450 fn drv_renesas_xhci_init() -> bool { shell_print_string("Loading Renesas xHCI USB 3.0...\n" as ptr<u8>); return true; }
8451 fn drv_asmedia_xhci_init() -> bool { shell_print_string("Loading ASMedia xHCI USB 3.0/3.1...\n" as ptr<u8>); return true; }
8452 fn drv_via_xhci_init() -> bool { shell_print_string("Loading VIA xHCI USB 3.0...\n" as ptr<u8>); return true; }
8453 fn drv_ti_xhci_init() -> bool { shell_print_string("Loading Texas Instruments xHCI USB 3.0...\n" as ptr<u8>); return true; }
8454 fn drv_ti_firewire_init() -> bool { shell_print_string("Loading Texas Instruments IEEE 1394...\n" as ptr<u8>); return true; }
8455 fn drv_via_firewire_init() -> bool { shell_print_string("Loading VIA IEEE 1394 Firewire...\n" as ptr<u8>); return true; }
8456 fn drv_ricoh_firewire_init() -> bool { shell_print_string("Loading Ricoh IEEE 1394 Firewire...\n" as ptr<u8>); return true; }
8457 fn drv_ricoh_sd_init() -> bool { shell_print_string("Loading Ricoh SD/MMC Host Controller...\n" as ptr<u8>); return true; }
8458 fn drv_o2micro_sd_init() -> bool { shell_print_string("Loading O2Micro SD/MMC Host Controller...\n" as ptr<u8>); return true; }
8459 fn drv_ene_sd_init() -> bool { shell_print_string("Loading ENE Technology SD Host Controller...\n" as ptr<u8>); return true; }
8460
8461 fn uda_register_extended_drivers() {
8462 register_driver("lsi_megaraid" as ptr<u8>, 2, drv_lsi_megaraid_init as u64, 0, 0, 0);
8463 register_driver("adaptec_raid" as ptr<u8>, 2, drv_adaptec_raid_init as u64, 0, 0, 0);
8464 register_driver("promise_raid" as ptr<u8>, 2, drv_promise_fasttrak_init as u64, 0, 0, 0);
8465 register_driver("highpoint_raid" as ptr<u8>, 2, drv_highpoint_rocketraid_init as u64, 0, 0, 0);
8466 register_driver("via_sata" as ptr<u8>, 2, drv_via_sata_init as u64, 0, 0, 0);
8467 register_driver("sis_sata" as ptr<u8>, 2, drv_sis_sata_init as u64, 0, 0, 0);
8468 register_driver("uli_sata" as ptr<u8>, 2, drv_uli_sata_init as u64, 0, 0, 0);
8469 register_driver("marvell_sata" as ptr<u8>, 2, drv_marvell_sata_init as u64, 0, 0, 0);
8470 register_driver("jmicron_sata" as ptr<u8>, 2, drv_jmicron_sata_init as u64, 0, 0, 0);
8471 register_driver("asmedia_sata" as ptr<u8>, 2, drv_asmedia_sata_init as u64, 0, 0, 0);
8472 register_driver("mellanox_cx" as ptr<u8>, 1, drv_mellanox_cx_init as u64, 0, 0, 0);
8473 register_driver("3com_3c905" as ptr<u8>, 1, drv_3com_3c905_init as u64, 0, 0, 0);
8474 register_driver("dec_tulip" as ptr<u8>, 1, drv_dec_tulip_init as u64, 0, 0, 0);
8475 register_driver("sis_900" as ptr<u8>, 1, drv_sis_900_init as u64, 0, 0, 0);
8476 register_driver("via_rhine" as ptr<u8>, 1, drv_via_rhine_init as u64, 0, 0, 0);
8477 register_driver("via_velocity" as ptr<u8>, 1, drv_via_velocity_init as u64, 0, 0, 0);
8478 register_driver("marvell_yukon" as ptr<u8>, 1, drv_marvell_yukon_init as u64, 0, 0, 0);
8479 register_driver("bcm_tg3" as ptr<u8>, 1, drv_broadcom_tg3_init as u64, 0, 0, 0);
8480 register_driver("intel_10gbe_vf" as ptr<u8>, 1, drv_intel_10gbe_vf_init as u64, 0, 0, 0);
8481 register_driver("solarflare" as ptr<u8>, 1, drv_solarflare_init as u64, 0, 0, 0);
8482 register_driver("qlogic_net" as ptr<u8>, 1, drv_qlogic_net_init as u64, 0, 0, 0);
8483 register_driver("matrox_g400" as ptr<u8>, 3, drv_matrox_g400_init as u64, 0, 0, 0);
8484 register_driver("3dfx_voodoo" as ptr<u8>, 3, drv_3dfx_voodoo_init as u64, 0, 0, 0);
8485 register_driver("cirrus_logic" as ptr<u8>, 3, drv_cirrus_logic_init as u64, 0, 0, 0);
8486 register_driver("s3_trio" as ptr<u8>, 3, drv_s3_trio_init as u64, 0, 0, 0);
8487 register_driver("s3_savage" as ptr<u8>, 3, drv_s3_savage_init as u64, 0, 0, 0);
8488 register_driver("via_chrome" as ptr<u8>, 3, drv_via_chrome_init as u64, 0, 0, 0);
8489 register_driver("sb_live" as ptr<u8>, 4, drv_creative_emu10k1_init as u64, 0, 0, 0);
8490 register_driver("sb_xifi" as ptr<u8>, 4, drv_creative_xifi_init as u64, 0, 0, 0);
8491 register_driver("via_envy24" as ptr<u8>, 4, drv_via_envy24_init as u64, 0, 0, 0);
8492 register_driver("cmi8738" as ptr<u8>, 4, drv_cmedia_cmi8738_init as u64, 0, 0, 0);
8493 register_driver("cmedia_oxygen" as ptr<u8>, 4, drv_cmedia_oxygen_init as u64, 0, 0, 0);
8494 register_driver("ess_solo1" as ptr<u8>, 4, drv_ess_solo1_init as u64, 0, 0, 0);
8495 register_driver("ymf724" as ptr<u8>, 4, drv_yamaha_ymf724_init as u64, 0, 0, 0);
8496 register_driver("fresco_xhci" as ptr<u8>, 6, drv_fresco_logic_xhci_init as u64, 0, 0, 0);
8497 register_driver("renesas_xhci" as ptr<u8>, 6, drv_renesas_xhci_init as u64, 0, 0, 0);
8498 register_driver("asmedia_xhci" as ptr<u8>, 6, drv_asmedia_xhci_init as u64, 0, 0, 0);
8499 register_driver("via_xhci" as ptr<u8>, 6, drv_via_xhci_init as u64, 0, 0, 0);
8500 register_driver("ti_xhci" as ptr<u8>, 6, drv_ti_xhci_init as u64, 0, 0, 0);
8501 register_driver("ti_firewire" as ptr<u8>, 2, drv_ti_firewire_init as u64, 0, 0, 0);
8502 register_driver("via_firewire" as ptr<u8>, 2, drv_via_firewire_init as u64, 0, 0, 0);
8503 register_driver("ricoh_firewire" as ptr<u8>, 2, drv_ricoh_firewire_init as u64, 0, 0, 0);
8504 register_driver("ricoh_sd" as ptr<u8>, 2, drv_ricoh_sd_init as u64, 0, 0, 0);
8505 register_driver("o2micro_sd" as ptr<u8>, 2, drv_o2micro_sd_init as u64, 0, 0, 0);
8506 register_driver("ene_sd" as ptr<u8>, 2, drv_ene_sd_init as u64, 0, 0, 0);
8507 }
8508
8509 fn get_pci_vendor_name_ext(vendor_id: u16) -> ptr<u8> {
8510 if vendor_id == 0x8086 { return "Intel Corporation" as ptr<u8>; }
8511 if vendor_id == 0x1002 { return "Advanced Micro Devices, Inc. [AMD/ATI]" as ptr<u8>; }
8512 if vendor_id == 0x10DE { return "NVIDIA Corporation" as ptr<u8>; }
8513 if vendor_id == 0x10EC { return "Realtek Semiconductor Co., Ltd." as ptr<u8>; }
8514 if vendor_id == 0x14E4 { return "Broadcom Inc. and subsidiaries" as ptr<u8>; }
8515 if vendor_id == 0x1AF4 { return "Red Hat, Inc. [Virtio]" as ptr<u8>; }
8516 if vendor_id == 0x15AD { return "VMware" as ptr<u8>; }
8517 if vendor_id == 0x80EE { return "InnoTek Systemberatung GmbH [VirtualBox]" as ptr<u8>; }
8518 if vendor_id == 0x1022 { return "Advanced Micro Devices, Inc. [AMD]" as ptr<u8>; }
8519 if vendor_id == 0x104C { return "Texas Instruments" as ptr<u8>; }
8520 if vendor_id == 0x11AB { return "Marvell Technology Group Ltd." as ptr<u8>; }
8521 if vendor_id == 0x197B { return "JMicron Technology Corp." as ptr<u8>; }
8522 if vendor_id == 0x1014 { return "IBM Corporation" as ptr<u8>; }
8523 if vendor_id == 0x103C { return "Hewlett-Packard Company" as ptr<u8>; }
8524 if vendor_id == 0x1028 { return "Dell" as ptr<u8>; }
8525 if vendor_id == 0x1043 { return "ASUSTeK Computer Inc." as ptr<u8>; }
8526 if vendor_id == 0x1458 { return "Gigabyte Technology Co., Ltd" as ptr<u8>; }
8527 if vendor_id == 0x1462 { return "Micro-Star International Co., Ltd. [MSI]" as ptr<u8>; }
8528 if vendor_id == 0x15B3 { return "Mellanox Technologies" as ptr<u8>; }
8529 if vendor_id == 0x1B36 { return "Red Hat, Inc. [QEMU]" as ptr<u8>; }
8530 if vendor_id == 0x144D { return "Samsung Electronics Co Ltd" as ptr<u8>; }
8531 if vendor_id == 0x152D { return "JMicron Technology Corp. [NVMe]" as ptr<u8>; }
8532 if vendor_id == 0x1D0F { return "Amazon.com, Inc." as ptr<u8>; }
8533 if vendor_id == 0x1AE0 { return "Google, Inc." as ptr<u8>; }
8534 if vendor_id == 0x106B { return "Apple Inc." as ptr<u8>; }
8535 if vendor_id == 0x105A { return "Promise Technology, Inc." as ptr<u8>; }
8536 if vendor_id == 0x10B5 { return "PLX Technology, Inc." as ptr<u8>; }
8537 if vendor_id == 0x10DF { return "Emulex Corporation" as ptr<u8>; }
8538 if vendor_id == 0x1106 { return "VIA Technologies, Inc." as ptr<u8>; }
8539 if vendor_id == 0x1179 { return "Toshiba Corporation" as ptr<u8>; }
8540 if vendor_id == 0x1186 { return "D-Link System Inc" as ptr<u8>; }
8541 if vendor_id == 0x13F0 { return "Sundance Technology Inc / IC Plus Corp" as ptr<u8>; }
8542 if vendor_id == 0x168C { return "Qualcomm Atheros" as ptr<u8>; }
8543 if vendor_id == 0x1814 { return "Ralink corp." as ptr<u8>; }
8544 if vendor_id == 0x1B21 { return "ASMedia Technology Inc." as ptr<u8>; }
8545 if vendor_id == 0x8087 { return "Intel Corporation [Wireless]" as ptr<u8>; }
8546 if vendor_id == 0x1000 { return "LSI Logic / Symbios Logic" as ptr<u8>; }
8547 if vendor_id == 0x9005 { return "Adaptec" as ptr<u8>; }
8548 if vendor_id == 0x102B { return "Matrox Electronics Systems Ltd." as ptr<u8>; }
8549 if vendor_id == 0x121A { return "3Dfx Interactive, Inc." as ptr<u8>; }
8550 if vendor_id == 0x1013 { return "Cirrus Logic" as ptr<u8>; }
8551 if vendor_id == 0x104B { return "BusLogic" as ptr<u8>; }
8552 if vendor_id == 0x10EA { return "Intergraphics" as ptr<u8>; }
8553 if vendor_id == 0x108E { return "Sun Microsystems Computer Corp." as ptr<u8>; }
8554 if vendor_id == 0x1011 { return "Digital Equipment Corporation" as ptr<u8>; }
8555 if vendor_id == 0x10B7 { return "3Com Corporation" as ptr<u8>; }
8556 if vendor_id == 0x10D9 { return "Macronix, Inc. [MXIC]" as ptr<u8>; }
8557 if vendor_id == 0x1113 { return "Accton Technology Corporation" as ptr<u8>; }
8558 if vendor_id == 0x11AD { return "Lite-On Communications Inc" as ptr<u8>; }
8559 if vendor_id == 0x1259 { return "Allied Telesyn International" as ptr<u8>; }
8560 if vendor_id == 0x1371 { return "Creative Labs" as ptr<u8>; }
8561 if vendor_id == 0x1102 { return "Creative Labs [Audio]" as ptr<u8>; }
8562 if vendor_id == 0x13F6 { return "C-Media Electronics Inc" as ptr<u8>; }
8563 if vendor_id == 0x109E { return "Brooktree Corporation" as ptr<u8>; }
8564 if vendor_id == 0x10CC { return "Ericsson Microelectronics" as ptr<u8>; }
8565 if vendor_id == 0x12D8 { return "Pericom Semiconductor" as ptr<u8>; }
8566 if vendor_id == 0x1B73 { return "Fresco Logic" as ptr<u8>; }
8567 if vendor_id == 0x1912 { return "Renesas Technology Corp." as ptr<u8>; }
8568 if vendor_id == 0x1180 { return "Ricoh Co Ltd" as ptr<u8>; }
8569 if vendor_id == 0x1217 { return "O2 Micro, Inc." as ptr<u8>; }
8570 if vendor_id == 0x1524 { return "ENE Technology Inc" as ptr<u8>; }
8571 if vendor_id == 0x125D { return "ESS Technology" as ptr<u8>; }
8572 if vendor_id == 0x1073 { return "Yamaha Corporation" as ptr<u8>; }
8573 if vendor_id == 0x1039 { return "Silicon Integrated Systems [SiS]" as ptr<u8>; }
8574 if vendor_id == 0x10B9 { return "ULi Electronics Inc." as ptr<u8>; }
8575 if vendor_id == 0x5333 { return "S3 Graphics Ltd." as ptr<u8>; }
8576 return "Unknown Device Vendor" as ptr<u8>;
8577 }
8578
8579 fn get_pci_device_name_ext(vendor_id: u16, device_id: u16) -> ptr<u8> {
8580 if vendor_id == 0x8086 {
8581 if device_id == 0x100E { return "82540EM Gigabit Ethernet Controller" as ptr<u8>; }
8582 if device_id == 0x100F { return "82545EM Gigabit Ethernet Controller" as ptr<u8>; }
8583 if device_id == 0x10D3 { return "82574L Gigabit Network Connection" as ptr<u8>; }
8584 if device_id == 0x10EA { return "82577LM Gigabit Network Connection" as ptr<u8>; }
8585 if device_id == 0x1502 { return "82579LM Gigabit Network Connection" as ptr<u8>; }
8586 if device_id == 0x1503 { return "82579V Gigabit Network Connection" as ptr<u8>; }
8587 if device_id == 0x153A { return "I217-LM Gigabit Network Connection" as ptr<u8>; }
8588 if device_id == 0x153B { return "I217-V Gigabit Network Connection" as ptr<u8>; }
8589 if device_id == 0x15B7 { return "I219-LM Gigabit Network Connection" as ptr<u8>; }
8590 if device_id == 0x15B8 { return "I219-V Gigabit Network Connection" as ptr<u8>; }
8591 if device_id == 0x10FB { return "82599ES 10-Gigabit SFI/SFP+ Network Connection" as ptr<u8>; }
8592 if device_id == 0x1528 { return "Ethernet Controller 10-Gigabit X540-AT2" as ptr<u8>; }
8593 if device_id == 0x2922 { return "82801IR/IO/P (ICH9) 6 port SATA Controller" as ptr<u8>; }
8594 if device_id == 0x1C02 { return "6 Series/C200 Series Chipset Family 6 port SATA" as ptr<u8>; }
8595 if device_id == 0x1E02 { return "7 Series/C210 Series Chipset Family 6-port SATA" as ptr<u8>; }
8596 if device_id == 0x8C02 { return "8 Series/C220 Series Chipset Family 6-port SATA" as ptr<u8>; }
8597 if device_id == 0xA102 { return "100 Series/C230 Series Chipset Family SATA" as ptr<u8>; }
8598 if device_id == 0xA282 { return "200 Series/Z370 Chipset Family SATA AHCI" as ptr<u8>; }
8599 if device_id == 0x0116 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
8600 if device_id == 0x0166 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
8601 if device_id == 0x0412 { return "4th Gen Core Processor Integrated Graphics" as ptr<u8>; }
8602 if device_id == 0x1912 { return "HD Graphics 530" as ptr<u8>; }
8603 if device_id == 0x3E92 { return "UHD Graphics 630 (Desktop)" as ptr<u8>; }
8604 if device_id == 0x9BC5 { return "CometLake-S GT2 [UHD Graphics 630]" as ptr<u8>; }
8605 if device_id == 0x2668 { return "82801FB/FBM/FR/FW/FRW High Definition Audio" as ptr<u8>; }
8606 if device_id == 0x284B { return "82801H (ICH8 Family) High Definition Audio" as ptr<u8>; }
8607 if device_id == 0x293E { return "82801I (ICH9 Family) High Definition Audio" as ptr<u8>; }
8608 if device_id == 0x1E20 { return "7 Series/C210 Series Chipset High Definition Audio" as ptr<u8>; }
8609 if device_id == 0xA170 { return "100 Series/C230 Series Chipset HD Audio" as ptr<u8>; }
8610 if device_id == 0x8C31 { return "8 Series/C220 Series Chipset Family USB xHCI" as ptr<u8>; }
8611 if device_id == 0xA12F { return "100 Series/C230 Series Chipset USB 3.0 xHCI" as ptr<u8>; }
8612 if device_id == 0x1E2D { return "7 Series/C210 Series Chipset USB Enhanced" as ptr<u8>; }
8613 if device_id == 0x24C2 { return "82801DB/DBM (ICH4/ICH4-M) USB UHCI" as ptr<u8>; }
8614 if device_id == 0xF1A5 { return "NVMe SSD Controller (Optane/760p)" as ptr<u8>; }
8615 if device_id == 0x4220 { return "PRO/Wireless 2200BG Network Connection" as ptr<u8>; }
8616 if device_id == 0x4229 { return "PRO/Wireless 4965 AG or AGN Network Connection" as ptr<u8>; }
8617 if device_id == 0x0085 { return "Centrino Advanced-N 6205 [Taylor Peak]" as ptr<u8>; }
8618 if device_id == 0x08B1 { return "Wireless 7260" as ptr<u8>; }
8619 if device_id == 0x24FB { return "Dual Band Wireless-AC 3160" as ptr<u8>; }
8620 if device_id == 0x24FD { return "Dual Band Wireless-AC 8265" as ptr<u8>; }
8621 if device_id == 0x2723 { return "Wi-Fi 6 AX200" as ptr<u8>; }
8622 if device_id == 0x2725 { return "Wi-Fi 6 AX210/AX1675 2x2" as ptr<u8>; }
8623 if device_id == 0x7113 { return "PIIX4/4E/4M IDE Controller" as ptr<u8>; }
8624 if device_id == 0x1237 { return "440FX - 82441FX PMC" as ptr<u8>; }
8625 if device_id == 0x7000 { return "82371SB PIIX3 ISA" as ptr<u8>; }
8626 if device_id == 0x7110 { return "82371AB/EB/MB PIIX4 ISA" as ptr<u8>; }
8627 if device_id == 0x7111 { return "82371AB/EB/MB PIIX4 IDE" as ptr<u8>; }
8628 if device_id == 0x7112 { return "82371AB/EB/MB PIIX4 USB" as ptr<u8>; }
8629 return "Intel Controller" as ptr<u8>;
8630 }
8631 if vendor_id == 0x10EC {
8632 if device_id == 0x8139 { return "RTL-8100/8101L/8139 PCI Fast Ethernet" as ptr<u8>; }
8633 if device_id == 0x8168 { return "RTL8111/8168/8411 PCI Express Gigabit" as ptr<u8>; }
8634 if device_id == 0x8169 { return "RTL8169 PCI Gigabit Ethernet" as ptr<u8>; }
8635 if device_id == 0x8125 { return "RTL8125 2.5GbE Controller" as ptr<u8>; }
8636 if device_id == 0x818B { return "RTL8192EE PCIe Wireless Network Adapter" as ptr<u8>; }
8637 if device_id == 0x8821 { return "RTL8821AE 802.11ac PCIe Wireless" as ptr<u8>; }
8638 if device_id == 0x8822 { return "RTL8822BE 802.11a/b/g/n/ac WiFi" as ptr<u8>; }
8639 if device_id == 0x522A { return "RTS522A PCI Express Card Reader" as ptr<u8>; }
8640 if device_id == 0x0282 { return "RTL8188EE Wireless Network Adapter" as ptr<u8>; }
8641 if device_id == 0x8161 { return "RTL8162 Fast Ethernet" as ptr<u8>; }
8642 if device_id == 0x8167 { return "RTL8167 Gigabit Ethernet" as ptr<u8>; }
8643 if device_id == 0x5209 { return "RTS5209 PCI Express Card Reader" as ptr<u8>; }
8644 if device_id == 0x5227 { return "RTS5227 PCI Express Card Reader" as ptr<u8>; }
8645 if device_id == 0x5289 { return "RTL8411B PCI Express Card Reader" as ptr<u8>; }
8646 return "Realtek Device" as ptr<u8>;
8647 }
8648 if vendor_id == 0x10DE {
8649 if device_id == 0x0402 { return "GeForce 8600 GT" as ptr<u8>; }
8650 if device_id == 0x0611 { return "GeForce 8800 GT" as ptr<u8>; }
8651 if device_id == 0x0A20 { return "GeForce GT 220" as ptr<u8>; }
8652 if device_id == 0x06C0 { return "GeForce GTX 480" as ptr<u8>; }
8653 if device_id == 0x1080 { return "GeForce GTX 580" as ptr<u8>; }
8654 if device_id == 0x1180 { return "GeForce GTX 680" as ptr<u8>; }
8655 if device_id == 0x13C2 { return "GeForce GTX 970" as ptr<u8>; }
8656 if device_id == 0x13C0 { return "GeForce GTX 980" as ptr<u8>; }
8657 if device_id == 0x1C03 { return "GeForce GTX 1060 6GB" as ptr<u8>; }
8658 if device_id == 0x1B81 { return "GeForce GTX 1070" as ptr<u8>; }
8659 if device_id == 0x1B06 { return "GeForce GTX 1080 Ti" as ptr<u8>; }
8660 if device_id == 0x1E84 { return "GeForce RTX 2070" as ptr<u8>; }
8661 if device_id == 0x1E07 { return "GeForce RTX 2080 Ti" as ptr<u8>; }
8662 if device_id == 0x2204 { return "GeForce RTX 3090" as ptr<u8>; }
8663 if device_id == 0x2484 { return "GeForce RTX 3070" as ptr<u8>; }
8664 if device_id == 0x2684 { return "GeForce RTX 4090" as ptr<u8>; }
8665 if device_id == 0x28E0 { return "GeForce RTX 4050 Laptop GPU" as ptr<u8>; }
8666 if device_id == 0x0E0A { return "GF119 HDMI Audio Controller" as ptr<u8>; }
8667 if device_id == 0x0FB0 { return "GM200 High Definition Audio" as ptr<u8>; }
8668 if device_id == 0x10F0 { return "GP104 High Definition Audio" as ptr<u8>; }
8669 if device_id == 0x10FA { return "TU104 HD Audio Controller" as ptr<u8>; }
8670 if device_id == 0x0059 { return "CK804 Serial ATA Controller" as ptr<u8>; }
8671 if device_id == 0x0054 { return "CK804 Memory Controller" as ptr<u8>; }
8672 if device_id == 0x0055 { return "CK804 IDE" as ptr<u8>; }
8673 if device_id == 0x03EF { return "MCP61 Ethernet" as ptr<u8>; }
8674 if device_id == 0x0DF4 { return "GeForce GT 540M" as ptr<u8>; }
8675 if device_id == 0x0FC6 { return "GeForce GTX 650" as ptr<u8>; }
8676 if device_id == 0x1140 { return "GF117M [GeForce 610M/710M]" as ptr<u8>; }
8677 if device_id == 0x139A { return "GM107M [GeForce GTX 950M]" as ptr<u8>; }
8678 if device_id == 0x1C20 { return "GP106M [GeForce GTX 1060 Mobile]" as ptr<u8>; }
8679 if device_id == 0x1F11 { return "TU106M [GeForce RTX 2060 Mobile]" as ptr<u8>; }
8680 if device_id == 0x2520 { return "GA106M [GeForce RTX 3060 Mobile]" as ptr<u8>; }
8681 return "NVIDIA Graphics / Multimedia" as ptr<u8>;
8682 }
8683 if vendor_id == 0x1002 {
8684 if device_id == 0x6738 { return "Radeon HD 6870" as ptr<u8>; }
8685 if device_id == 0x6798 { return "Radeon HD 7970 / R9 280X" as ptr<u8>; }
8686 if device_id == 0x67B1 { return "Radeon R9 290 / 390" as ptr<u8>; }
8687 if device_id == 0x67DF { return "Radeon RX 470/480/570/580/590" as ptr<u8>; }
8688 if device_id == 0x687F { return "Radeon RX Vega 56/64" as ptr<u8>; }
8689 if device_id == 0x731F { return "Radeon RX 5700 XT" as ptr<u8>; }
8690 if device_id == 0x73BF { return "Radeon RX 6800 XT / 6900 XT" as ptr<u8>; }
8691 if device_id == 0x744C { return "Radeon RX 7900 XTX" as ptr<u8>; }
8692 if device_id == 0x4383 { return "SB7x0/SB8x0/SB9x0 High Definition Audio" as ptr<u8>; }
8693 if device_id == 0x1457 { return "Family 17h HD Audio Controller" as ptr<u8>; }
8694 if device_id == 0x4391 { return "SB7x0/SB8x0/SB9x0 SATA [AHCI]" as ptr<u8>; }
8695 if device_id == 0x7901 { return "FCH SATA Controller [AHCI]" as ptr<u8>; }
8696 if device_id == 0x515E { return "Radeon X1300/X1550" as ptr<u8>; }
8697 if device_id == 0x9540 { return "Radeon HD 4350/4550" as ptr<u8>; }
8698 if device_id == 0x68B8 { return "Radeon HD 5770" as ptr<u8>; }
8699 if device_id == 0x6819 { return "Radeon HD 7870" as ptr<u8>; }
8700 if device_id == 0x15D8 { return "Raven Ridge [Radeon Vega Series]" as ptr<u8>; }
8701 if device_id == 0x1636 { return "Renoir [Radeon Vega Series]" as ptr<u8>; }
8702 if device_id == 0x73A5 { return "Navi 22 [Radeon RX 6700/6700 XT]" as ptr<u8>; }
8703 if device_id == 0x7480 { return "Navi 31 [Radeon RX 7900 XT]" as ptr<u8>; }
8704 return "AMD/ATI Display / Multimedia" as ptr<u8>;
8705 }
8706 if vendor_id == 0x1AF4 {
8707 if device_id == 0x1000 { return "VirtIO Network Device" as ptr<u8>; }
8708 if device_id == 0x1001 { return "VirtIO Block Device" as ptr<u8>; }
8709 if device_id == 0x1002 { return "VirtIO Memory Balloon" as ptr<u8>; }
8710 if device_id == 0x1003 { return "VirtIO Console" as ptr<u8>; }
8711 if device_id == 0x1004 { return "VirtIO SCSI" as ptr<u8>; }
8712 if device_id == 0x1005 { return "VirtIO RNG" as ptr<u8>; }
8713 if device_id == 0x1041 { return "VirtIO Network Device (Modern)" as ptr<u8>; }
8714 if device_id == 0x1042 { return "VirtIO Block Device (Modern)" as ptr<u8>; }
8715 if device_id == 0x1050 { return "VirtIO GPU" as ptr<u8>; }
8716 if device_id == 0x1052 { return "VirtIO Input Device" as ptr<u8>; }
8717 if device_id == 0x1053 { return "VirtIO Socket Device" as ptr<u8>; }
8718 return "VirtIO Standard Device" as ptr<u8>;
8719 }
8720 if vendor_id == 0x15AD {
8721 if device_id == 0x0405 { return "VMware SVGA II Adapter" as ptr<u8>; }
8722 if device_id == 0x07B0 { return "VMware VMXNET3 Ethernet" as ptr<u8>; }
8723 if device_id == 0x07A0 { return "VMware PVSCSI SCSI" as ptr<u8>; }
8724 if device_id == 0x0770 { return "VMware USB2 EHCI" as ptr<u8>; }
8725 if device_id == 0x0774 { return "VMware USB1 UHCI" as ptr<u8>; }
8726 return "VMware Virtual Device" as ptr<u8>;
8727 }
8728 if vendor_id == 0x80EE {
8729 if device_id == 0xBEEF { return "VirtualBox Graphics Adapter" as ptr<u8>; }
8730 if device_id == 0xCAFE { return "VirtualBox Guest Service" as ptr<u8>; }
8731 return "VirtualBox Virtual Device" as ptr<u8>;
8732 }
8733 if vendor_id == 0x144D {
8734 if device_id == 0xA802 { return "Samsung SM951 NVMe" as ptr<u8>; }
8735 if device_id == 0xA804 { return "Samsung 960 EVO/PRO NVMe" as ptr<u8>; }
8736 if device_id == 0xA808 { return "Samsung 970 EVO/PRO NVMe" as ptr<u8>; }
8737 if device_id == 0xA80A { return "Samsung 980 PRO NVMe" as ptr<u8>; }
8738 if device_id == 0xA80C { return "Samsung 990 PRO NVMe" as ptr<u8>; }
8739 if device_id == 0xA809 { return "Samsung PM9A1 NVMe" as ptr<u8>; }
8740 return "Samsung NVMe Controller" as ptr<u8>;
8741 }
8742 if vendor_id == 0x14E4 {
8743 if device_id == 0x1659 { return "NetXtreme BCM5721 Gigabit" as ptr<u8>; }
8744 if device_id == 0x1677 { return "NetXtreme BCM5751 Gigabit" as ptr<u8>; }
8745 if device_id == 0x4311 { return "BCM4311 802.11b/g WLAN" as ptr<u8>; }
8746 if device_id == 0x4322 { return "BCM4322 802.11a/b/g/n Wireless" as ptr<u8>; }
8747 if device_id == 0x4360 { return "BCM4360 802.11ac Wireless" as ptr<u8>; }
8748 if device_id == 0x1692 { return "NetLink BCM57780 Gigabit" as ptr<u8>; }
8749 if device_id == 0x4331 { return "BCM4331 802.11a/b/g/n" as ptr<u8>; }
8750 if device_id == 0x43A0 { return "BCM4360 802.11ac Wireless" as ptr<u8>; }
8751 return "Broadcom Communications" as ptr<u8>;
8752 }
8753 if vendor_id == 0x168C {
8754 if device_id == 0x002B { return "AR9285 Wireless Network Adapter" as ptr<u8>; }
8755 if device_id == 0x002E { return "AR9287 Wireless Network Adapter" as ptr<u8>; }
8756 if device_id == 0x0032 { return "AR9485 Wireless Network Adapter" as ptr<u8>; }
8757 if device_id == 0x003C { return "QCA986x/988x 802.11ac Wireless" as ptr<u8>; }
8758 if device_id == 0x0013 { return "AR5212/AR5213 Wireless Network Adapter" as ptr<u8>; }
8759 if device_id == 0x001C { return "AR2424 Wireless Network Adapter" as ptr<u8>; }
8760 if device_id == 0x0030 { return "AR9300 Wireless Network Adapter" as ptr<u8>; }
8761 if device_id == 0x003E { return "QCA6174 802.11ac Wireless" as ptr<u8>; }
8762 if device_id == 0x0042 { return "QCA9377 802.11ac Wireless" as ptr<u8>; }
8763 return "Atheros Wireless Device" as ptr<u8>;
8764 }
8765 if vendor_id == 0x1000 {
8766 if device_id == 0x0054 { return "MegaRAID SAS 2008" as ptr<u8>; }
8767 if device_id == 0x005B { return "MegaRAID SAS 2108" as ptr<u8>; }
8768 if device_id == 0x005D { return "MegaRAID SAS 2208" as ptr<u8>; }
8769 if device_id == 0x005F { return "MegaRAID SAS 3008" as ptr<u8>; }
8770 if device_id == 0x00cf { return "MegaRAID SAS 3108" as ptr<u8>; }
8771 return "LSI Logic Storage Controller" as ptr<u8>;
8772 }
8773 if vendor_id == 0x1102 {
8774 if device_id == 0x0002 { return "Sound Blaster Live! (EMU10K1)" as ptr<u8>; }
8775 if device_id == 0x0004 { return "Sound Blaster Audigy (EMU10K2)" as ptr<u8>; }
8776 if device_id == 0x0005 { return "Sound Blaster X-Fi" as ptr<u8>; }
8777 if device_id == 0x000A { return "Sound Blaster X-Fi Titanium" as ptr<u8>; }
8778 if device_id == 0x0012 { return "Sound Blaster Recon3D" as ptr<u8>; }
8779 return "Creative Audio Device" as ptr<u8>;
8780 }
8781 if vendor_id == 0x1011 {
8782 if device_id == 0x0009 { return "DECchip 21140 [FasterNet]" as ptr<u8>; }
8783 if device_id == 0x0019 { return "DECchip 21142/43" as ptr<u8>; }
8784 return "DEC Ethernet Controller" as ptr<u8>;
8785 }
8786 if vendor_id == 0x10B7 {
8787 if device_id == 0x9050 { return "3c905 100BaseTX" as ptr<u8>; }
8788 if device_id == 0x9055 { return "3c905B 100BaseTX" as ptr<u8>; }
8789 if device_id == 0x9200 { return "3c905C-TX/TX-M" as ptr<u8>; }
8790 return "3Com Fast Ethernet" as ptr<u8>;
8791 }
8792 if vendor_id == 0x11AB {
8793 if device_id == 0x4364 { return "88E8056 PCI-E Gigabit Ethernet" as ptr<u8>; }
8794 if device_id == 0x4380 { return "88E8057 PCI-E Gigabit Ethernet" as ptr<u8>; }
8795 if device_id == 0x9123 { return "88SE9123 PCIe SATA 6.0 Gb/s" as ptr<u8>; }
8796 if device_id == 0x9215 { return "88SE9215 PCIe SATA 6.0 Gb/s" as ptr<u8>; }
8797 return "Marvell Technology Device" as ptr<u8>;
8798 }
8799 if vendor_id == 0x1B21 {
8800 if device_id == 0x0612 { return "ASM1062 Serial ATA Controller" as ptr<u8>; }
8801 if device_id == 0x1042 { return "ASM1042 SuperSpeed USB Host" as ptr<u8>; }
8802 if device_id == 0x1142 { return "ASM1142 USB 3.1 Host" as ptr<u8>; }
8803 if device_id == 0x2142 { return "ASM2142 USB 3.1 Host" as ptr<u8>; }
8804 if device_id == 0x3242 { return "ASM3242 USB 3.2 Host" as ptr<u8>; }
8805 return "ASMedia Host Controller" as ptr<u8>;
8806 }
8807 if vendor_id == 0x1039 {
8808 if device_id == 0x0190 { return "SiS900 PCI Fast Ethernet" as ptr<u8>; }
8809 if device_id == 0x0191 { return "SiS191 Gigabit Ethernet" as ptr<u8>; }
8810 if device_id == 0x0180 { return "SiS180 SATA Controller" as ptr<u8>; }
8811 if device_id == 0x7012 { return "SiS7012 AC'97 Sound" as ptr<u8>; }
8812 if device_id == 0x7001 { return "SiS5597/5598/5600 USB UHCI" as ptr<u8>; }
8813 return "SiS Chipset Component" as ptr<u8>;
8814 }
8815 if vendor_id == 0x1106 {
8816 if device_id == 0x3065 { return "VT6102/VT6103 [Rhine-II]" as ptr<u8>; }
8817 if device_id == 0x3106 { return "VT6105/VT6106S [Rhine-III]" as ptr<u8>; }
8818 if device_id == 0x3119 { return "VT6120/VT6121/VT6122 Velocity Gigabit" as ptr<u8>; }
8819 if device_id == 0x3149 { return "VT6420 SATA RAID" as ptr<u8>; }
8820 if device_id == 0x3249 { return "VT6421 IDE RAID" as ptr<u8>; }
8821 if device_id == 0x0591 { return "VT82C598/694x [Apollo Pro]" as ptr<u8>; }
8822 if device_id == 0x3038 { return "VT82xxxxx UHCI USB 1.1" as ptr<u8>; }
8823 if device_id == 0x3104 { return "USB 2.0" as ptr<u8>; }
8824 if device_id == 0x3288 { return "VT8237A HD Audio Controller" as ptr<u8>; }
8825 if device_id == 0x3059 { return "VT8233/A/8235/8237 AC97 Audio" as ptr<u8>; }
8826 return "VIA Technologies Device" as ptr<u8>;
8827 }
8828 if vendor_id == 0x15B3 {
8829 if device_id == 0x1003 { return "MT27500 Family [ConnectX-3]" as ptr<u8>; }
8830 if device_id == 0x1013 { return "MT27700 Family [ConnectX-4]" as ptr<u8>; }
8831 if device_id == 0x1015 { return "MT27710 Family [ConnectX-4 Lx]" as ptr<u8>; }
8832 if device_id == 0x1017 { return "MT27800 Family [ConnectX-5]" as ptr<u8>; }
8833 if device_id == 0x101B { return "MT28908 Family [ConnectX-6]" as ptr<u8>; }
8834 return "Mellanox Network Adapter" as ptr<u8>;
8835 }
8836 if vendor_id == 0x121A {
8837 if device_id == 0x0001 { return "Voodoo Graphics" as ptr<u8>; }
8838 if device_id == 0x0002 { return "Voodoo 2" as ptr<u8>; }
8839 if device_id == 0x0003 { return "Voodoo Banshee" as ptr<u8>; }
8840 if device_id == 0x0004 { return "Voodoo 3" as ptr<u8>; }
8841 if device_id == 0x0005 { return "Voodoo 4/5" as ptr<u8>; }
8842 return "3Dfx Voodoo Accelerator" as ptr<u8>;
8843 }
8844 if vendor_id == 0x102B {
8845 if device_id == 0x0519 { return "MGA Millennium" as ptr<u8>; }
8846 if device_id == 0x051B { return "MGA Mystique" as ptr<u8>; }
8847 if device_id == 0x0521 { return "MGA G200" as ptr<u8>; }
8848 if device_id == 0x0525 { return "MGA G400/G450" as ptr<u8>; }
8849 if device_id == 0x2527 { return "MGA G550" as ptr<u8>; }
8850 return "Matrox Graphics" as ptr<u8>;
8851 }
8852 if vendor_id == 0x5333 {
8853 if device_id == 0x8811 { return "Trio32/64/64V+" as ptr<u8>; }
8854 if device_id == 0x8A01 { return "ViRGE/DX or /GX" as ptr<u8>; }
8855 if device_id == 0x8A22 { return "Savage 3D" as ptr<u8>; }
8856 if device_id == 0x8C10 { return "Savage/MX" as ptr<u8>; }
8857 if device_id == 0x8D04 { return "Savage4" as ptr<u8>; }
8858 if device_id == 0x8C2E { return "SuperSavage IX/C" as ptr<u8>; }
8859 return "S3 Graphics Device" as ptr<u8>;
8860 }
8861
8862 return "Generic Peripheral Component" as ptr<u8>;
8863 }
8864
8865 struct CpuState {
8866 ds: u16,
8867 es: u16,
8868 fs: u16,
8869 gs: u16,
8870 rax: u64,
8871 rbx: u64,
8872 rcx: u64,
8873 rdx: u64,
8874 rsi: u64,
8875 rdi: u64,
8876 rbp: u64,
8877 r8: u64,
8878 r9: u64,
8879 r10: u64,
8880 r11: u64,
8881 r12: u64,
8882 r13: u64,
8883 r14: u64,
8884 r15: u64,
8885 int_num: u64,
8886 error_code: u64,
8887 rip: u64,
8888 cs: u64,
8889 rflags: u64,
8890 rsp: u64,
8891 ss: u64,
8892 }
8893
8894 fn get_exception_name(vector: u64) -> ptr<u8> {
8895 if vector == 0 { return "Divide By Zero Exception" as ptr<u8>; }
8896 if vector == 1 { return "Debug Exception" as ptr<u8>; }
8897 if vector == 2 { return "Non-maskable Interrupt" as ptr<u8>; }
8898 if vector == 3 { return "Breakpoint Exception" as ptr<u8>; }
8899 if vector == 4 { return "Overflow Exception" as ptr<u8>; }
8900 if vector == 5 { return "Bound Range Exceeded" as ptr<u8>; }
8901 if vector == 6 { return "Invalid Opcode" as ptr<u8>; }
8902 if vector == 7 { return "Device Not Available" as ptr<u8>; }
8903 if vector == 8 { return "Double Fault" as ptr<u8>; }
8904 if vector == 9 { return "Coprocessor Segment Overrun" as ptr<u8>; }
8905 if vector == 10 { return "Invalid TSS" as ptr<u8>; }
8906 if vector == 11 { return "Segment Not Present" as ptr<u8>; }
8907 if vector == 12 { return "Stack-Segment Fault" as ptr<u8>; }
8908 if vector == 13 { return "General Protection Fault" as ptr<u8>; }
8909 if vector == 14 { return "Page Fault" as ptr<u8>; }
8910 if vector == 15 { return "Reserved" as ptr<u8>; }
8911 if vector == 16 { return "x87 Floating-Point Exception" as ptr<u8>; }
8912 if vector == 17 { return "Alignment Check" as ptr<u8>; }
8913 if vector == 18 { return "Machine Check" as ptr<u8>; }
8914 if vector == 19 { return "SIMD Floating-Point Exception" as ptr<u8>; }
8915 if vector == 20 { return "Virtualization Exception" as ptr<u8>; }
8916 if vector == 21 { return "Control Protection Exception" as ptr<u8>; }
8917 if vector == 28 { return "Hypervisor Injection Exception" as ptr<u8>; }
8918 if vector == 29 { return "VMM Communication Exception" as ptr<u8>; }
8919 if vector == 30 { return "Security Exception" as ptr<u8>; }
8920 return "Unknown Interrupt/Exception" as ptr<u8>;
8921 }
8922
8923 fn render_panic_screen(state: ptr<CpuState>, cr2: u64, cr3: u64) {
8924 panic_clear_screen(VGA_COLOR_WHITE_ON_RED);
8925
8926 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
8927 panic_write_padded_string(" W KERNEL PANIC - CRITICAL SYSTEM HALT " as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8928 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
8929
8930 panic_print_string("\nEXCEPTION: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8931 let ext_name = get_exception_name((*state).int_num);
8932 panic_print_string(ext_name, VGA_COLOR_WHITE_ON_RED);
8933 panic_print_string(" (" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8934 panic_print_hex((*state).int_num, VGA_COLOR_WHITE_ON_RED);
8935 panic_print_string(")\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8936
8937 panic_print_string("ERROR CODE: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8938 panic_print_hex((*state).error_code, VGA_COLOR_WHITE_ON_RED);
8939 panic_print_string("\n\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8940
8941 panic_write_padded_string("--- CPU REGISTERS ---" as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8942 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8943
8944 panic_print_string("RAX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8945 panic_print_hex((*state).rax, VGA_COLOR_WHITE_ON_RED);
8946 panic_print_string(" RBX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8947 panic_print_hex((*state).rbx, VGA_COLOR_WHITE_ON_RED);
8948 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8949
8950 panic_print_string("RCX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8951 panic_print_hex((*state).rcx, VGA_COLOR_WHITE_ON_RED);
8952 panic_print_string(" RDX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8953 panic_print_hex((*state).rdx, VGA_COLOR_WHITE_ON_RED);
8954 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8955
8956 panic_print_string("RSI: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8957 panic_print_hex((*state).rsi, VGA_COLOR_WHITE_ON_RED);
8958 panic_print_string(" RDI: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8959 panic_print_hex((*state).rdi, VGA_COLOR_WHITE_ON_RED);
8960 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8961
8962 panic_print_string("RBP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8963 panic_print_hex((*state).rbp, VGA_COLOR_WHITE_ON_RED);
8964 panic_print_string(" RSP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8965 panic_print_hex((*state).rsp, VGA_COLOR_WHITE_ON_RED);
8966 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8967
8968 panic_print_string("R8 : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8969 panic_print_hex((*state).r8, VGA_COLOR_WHITE_ON_RED);
8970 panic_print_string(" R9 : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8971 panic_print_hex((*state).r9, VGA_COLOR_WHITE_ON_RED);
8972 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8973
8974 panic_print_string("R10: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8975 panic_print_hex((*state).r10, VGA_COLOR_WHITE_ON_RED);
8976 panic_print_string(" R11: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8977 panic_print_hex((*state).r11, VGA_COLOR_WHITE_ON_RED);
8978 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8979
8980 panic_print_string("R12: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8981 panic_print_hex((*state).r12, VGA_COLOR_WHITE_ON_RED);
8982 panic_print_string(" R13: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8983 panic_print_hex((*state).r13, VGA_COLOR_WHITE_ON_RED);
8984 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8985
8986 panic_print_string("R14: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8987 panic_print_hex((*state).r14, VGA_COLOR_WHITE_ON_RED);
8988 panic_print_string(" R15: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8989 panic_print_hex((*state).r15, VGA_COLOR_WHITE_ON_RED);
8990 panic_print_string("\n\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8991
8992 panic_write_padded_string("--- CONTROL REGISTERS & SEGMENTS ---" as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8993 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8994
8995 panic_print_string("RIP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8996 panic_print_hex((*state).rip, VGA_COLOR_WHITE_ON_RED);
8997 panic_print_string(" RFL: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8998 panic_print_hex((*state).rflags, VGA_COLOR_WHITE_ON_RED);
8999 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9000
9001 panic_print_string("CR2: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9002 panic_print_hex(cr2, VGA_COLOR_WHITE_ON_RED);
9003 panic_print_string(" CR3: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9004 panic_print_hex(cr3, VGA_COLOR_WHITE_ON_RED);
9005 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9006
9007 panic_print_string("CS : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9008 panic_print_hex((*state).cs as u64, VGA_COLOR_WHITE_ON_RED);
9009 panic_print_string(" SS : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9010 panic_print_hex((*state).ss as u64, VGA_COLOR_WHITE_ON_RED);
9011 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9012 }
9013
9014 fn dump_stack_trace(rbp: u64, max_frames: u64) {
9015 panic_print_string("\n--- STACK TRACE ---\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9016 let mut current_rbp = rbp;
9017 let mut frame_count: u64 = 0;
9018
9019 while current_rbp != 0 {
9020 if frame_count >= max_frames {
9021 break;
9022 }
9023
9024 let rip_ptr = (current_rbp + 8) as ptr<u64>;
9025 let rip = *rip_ptr;
9026
9027 if rip == 0 {
9028 break;
9029 }
9030
9031 panic_print_string(" [" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9032 panic_print_hex(frame_count, VGA_COLOR_WHITE_ON_RED);
9033 panic_print_string("] " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9034 panic_print_hex(rip, VGA_COLOR_WHITE_ON_RED);
9035 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9036
9037 let next_rbp_ptr = current_rbp as ptr<u64>;
9038 current_rbp = *next_rbp_ptr;
9039 frame_count = frame_count + 1;
9040 }
9041 }
9042
9043 fn kernel_panic_handler(state: ptr<CpuState>) {
9044 let cr2_val: u64 = 0;
9045 let cr3_val: u64 = 0;
9046
9047 render_panic_screen(state, cr2_val, cr3_val);
9048 dump_stack_trace((*state).rbp, 8);
9049
9050 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
9051 panic_print_string("SYSTEM HALTED." as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
9052
9053 while true {}
9054 }
9055
9056 struct IdtEntry {
9057 base_low: u16,
9058 sel: u16,
9059 ist: u8,
9060 flags: u8,
9061 base_mid: u16,
9062 base_high: u32,
9063 reserved: u32,
9064 }
9065
9066 struct IdtPtr {
9067 limit: u16,
9068 base: u64,
9069 }
9070
9071 let mut idt: [IdtEntry; 256];
9072 let mut idtp: IdtPtr;
9073
9074 fn idt_set_gate(num: u8, base: u64, sel: u16, flags: u8) {
9075 let index = num as usize;
9076 idt[index].base_low = (base & 0xFFFF) as u16;
9077 idt[index].base_mid = ((base >> 16) & 0xFFFF) as u16;
9078 idt[index].base_high = (base >> 32) as u32;
9079 idt[index].sel = sel;
9080 idt[index].ist = 0;
9081 idt[index].flags = flags;
9082 idt[index].reserved = 0;
9083 }
9084
9085 fn idt_install() {
9086 idtp.limit = (256 * 16) - 1;
9087 idtp.base = &idt[0] as ptr<IdtEntry> as u64;
9088
9089 let mut i: u64 = 0;
9090 while i < 256 {
9091 idt_set_gate(i as u8, 0, 0x08, 0x8E);
9092 i = i + 1;
9093 }
9094 }
9095
9096 fn fault_divide_error(state: ptr<CpuState>) { kernel_panic_handler(state); }
9097 fn fault_debug(state: ptr<CpuState>) { kernel_panic_handler(state); }
9098 fn fault_nmi(state: ptr<CpuState>) { kernel_panic_handler(state); }
9099 fn fault_breakpoint(state: ptr<CpuState>) { kernel_panic_handler(state); }
9100 fn fault_overflow(state: ptr<CpuState>) { kernel_panic_handler(state); }
9101 fn fault_bounds(state: ptr<CpuState>) { kernel_panic_handler(state); }
9102 fn fault_invalid_opcode(state: ptr<CpuState>) { kernel_panic_handler(state); }
9103 fn fault_device_not_available(state: ptr<CpuState>) { kernel_panic_handler(state); }
9104 fn fault_double_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
9105 fn fault_coproc_segment_overrun(state: ptr<CpuState>) { kernel_panic_handler(state); }
9106 fn fault_invalid_tss(state: ptr<CpuState>) { kernel_panic_handler(state); }
9107 fn fault_segment_not_present(state: ptr<CpuState>) { kernel_panic_handler(state); }
9108 fn fault_stack_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
9109 fn fault_general_protection(state: ptr<CpuState>) { kernel_panic_handler(state); }
9110 fn fault_page_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
9111 fn fault_x87_fpu(state: ptr<CpuState>) { kernel_panic_handler(state); }
9112 fn fault_alignment_check(state: ptr<CpuState>) { kernel_panic_handler(state); }
9113 fn fault_machine_check(state: ptr<CpuState>) { kernel_panic_handler(state); }
9114 fn fault_simd_fpu(state: ptr<CpuState>) { kernel_panic_handler(state); }
9115 fn fault_virtualization(state: ptr<CpuState>) { kernel_panic_handler(state); }
9116
9117 struct Process {
9118 pid: u64,
9119 rsp: u64,
9120 rip: u64,
9121 cr3: u64,
9122 state: u8,
9123 time_slice: u64,
9124 }
9125
9126 let mut process_table: [Process; 256];
9127 let mut current_pid: u64 = 0;
9128 let mut total_processes: u64 = 0;
9129
9130 fn scheduler_init() {
9131 let mut i: u64 = 0;
9132 while i < 256 {
9133 process_table[i as usize].pid = 0;
9134 process_table[i as usize].state = 0;
9135 i = i + 1;
9136 }
9137 }
9138
9139 fn process_create(entry_point: u64, stack_pointer: u64, page_dir: u64) -> u64 {
9140 if total_processes >= 256 {
9141 return 0;
9142 }
9143
9144 let pid = total_processes + 1;
9145 let index = total_processes as usize;
9146
9147 process_table[index].pid = pid;
9148 process_table[index].rip = entry_point;
9149 process_table[index].rsp = stack_pointer;
9150 process_table[index].cr3 = page_dir;
9151 process_table[index].state = 1;
9152 process_table[index].time_slice = 15;
9153
9154 total_processes = total_processes + 1;
9155 return pid;
9156 }
9157
9158 fn schedule_next(current_rsp: u64) -> u64 {
9159 if total_processes == 0 {
9160 return current_rsp;
9161 }
9162
9163 if current_pid > 0 {
9164 let curr_idx = (current_pid - 1) as usize;
9165 process_table[curr_idx].rsp = current_rsp;
9166
9167 if process_table[curr_idx].time_slice > 0 {
9168 process_table[curr_idx].time_slice = process_table[curr_idx].time_slice - 1;
9169 if process_table[curr_idx].time_slice > 0 {
9170 return current_rsp;
9171 }
9172 }
9173 process_table[curr_idx].time_slice = 15;
9174 }
9175
9176 current_pid = current_pid + 1;
9177 if current_pid > total_processes {
9178 current_pid = 1;
9179 }
9180
9181 let next_idx = (current_pid - 1) as usize;
9182 return process_table[next_idx].rsp;
9183 }
9184
9185 fn timer_phase(hz: u32) {
9186 let divisor = 1193180 / hz;
9187 outb(0x43, 0x36);
9188 outb(0x40, (divisor & 0xFF) as u8);
9189 outb(0x40, ((divisor >> 8) & 0xFF) as u8);
9190 }
9191
9192 let mut timer_ticks: u64 = 0;
9193
9194 fn timer_handler(state: ptr<CpuState>) -> u64 {
9195 timer_ticks = timer_ticks + 1;
9196 let next_rsp = schedule_next((*state).rsp);
9197 outb(0x20, 0x20);
9198 return next_rsp;
9199 }
9200
9201 let mut memory_bitmap: [u64; 32768];
9202 let mut total_memory_pages: u64 = 0;
9203 let mut used_memory_pages: u64 = 0;
9204
9205 fn set_bit(bitmap: ptr<u64>, index: u64) {
9206 let array_index = index / 64;
9207 let bit_index = index % 64;
9208 let current = *(bitmap + array_index);
9209 *(bitmap + array_index) = current | (1 << bit_index);
9210 }
9211
9212 fn clear_bit(bitmap: ptr<u64>, index: u64) {
9213 let array_index = index / 64;
9214 let bit_index = index % 64;
9215 let current = *(bitmap + array_index);
9216 *(bitmap + array_index) = current & !(1 << bit_index);
9217 }
9218
9219 fn test_bit(bitmap: ptr<u64>, index: u64) -> u64 {
9220 let array_index = index / 64;
9221 let bit_index = index % 64;
9222 let current = *(bitmap + array_index);
9223 if (current & (1 << bit_index)) != 0 {
9224 return 1;
9225 }
9226 return 0;
9227 }
9228
9229 fn pmm_init(mem_size_kb: u64) {
9230 total_memory_pages = (mem_size_kb * 1024) / 4096;
9231 used_memory_pages = 0;
9232 let mut i: u64 = 0;
9233 while i < 32768 {
9234 memory_bitmap[i as usize] = 0;
9235 i = i + 1;
9236 }
9237 }
9238
9239 fn pmm_alloc_page() -> u64 {
9240 let mut i: u64 = 0;
9241 while i < total_memory_pages {
9242 if test_bit(&memory_bitmap[0] as ptr<u64>, i) == 0 {
9243 set_bit(&memory_bitmap[0] as ptr<u64>, i);
9244 used_memory_pages = used_memory_pages + 1;
9245 return i * 4096;
9246 }
9247 i = i + 1;
9248 }
9249 return 0;
9250 }
9251
9252 fn pmm_free_page(addr: u64) {
9253 let page_index = addr / 4096;
9254 clear_bit(&memory_bitmap[0] as ptr<u64>, page_index);
9255 used_memory_pages = used_memory_pages - 1;
9256 }
9257
9258 fn tlb_flush_single(addr: u64) {
9259 asm {
9260 "invlpg [%0]"
9261 :
9262 : "r" (addr)
9263 : "memory"
9264 }
9265 }
9266
9267 fn tlb_flush_all() {
9268 let mut cr3_val: u64 = 0;
9269 asm {
9270 "mov %0, cr3"
9271 "mov cr3, %0"
9272 : "=r" (cr3_val)
9273 :
9274 : "memory"
9275 }
9276 }
9277
9278 fn read_cr3() -> u64 {
9279 let mut cr3_val: u64 = 0;
9280 asm {
9281 "mov %0, cr3"
9282 : "=r" (cr3_val)
9283 }
9284 return cr3_val;
9285 }
9286
9287 fn write_cr3(val: u64) {
9288 asm {
9289 "mov cr3, %0"
9290 :
9291 : "r" (val)
9292 : "memory"
9293 }
9294 }
9295
9296 fn map_page(phys: u64, virt: u64, flags: u64) {
9297 let pml4_index = (virt >> 39) & 0x1FF;
9298 let pdpt_index = (virt >> 30) & 0x1FF;
9299 let pd_index = (virt >> 21) & 0x1FF;
9300 let pt_index = (virt >> 12) & 0x1FF;
9301
9302 let pml4 = read_cr3() as ptr<u64>;
9303 let mut pdpt_entry = *(pml4 + pml4_index);
9304
9305 if (pdpt_entry & 1) == 0 {
9306 let new_pdpt = pmm_alloc_page();
9307 *(pml4 + pml4_index) = new_pdpt | 3;
9308 pdpt_entry = new_pdpt | 3;
9309 }
9310
9311 let pdpt = (pdpt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9312 let mut pd_entry = *(pdpt + pdpt_index);
9313
9314 if (pd_entry & 1) == 0 {
9315 let new_pd = pmm_alloc_page();
9316 *(pdpt + pdpt_index) = new_pd | 3;
9317 pd_entry = new_pd | 3;
9318 }
9319
9320 let pd = (pd_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9321 let mut pt_entry = *(pd + pd_index);
9322
9323 if (pt_entry & 1) == 0 {
9324 let new_pt = pmm_alloc_page();
9325 *(pd + pd_index) = new_pt | 3;
9326 pt_entry = new_pt | 3;
9327 }
9328
9329 let pt = (pt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9330 *(pt + pt_index) = (phys & 0xFFFFFFFFFFFFF000) | (flags & 0xFFF) | 1;
9331
9332 tlb_flush_single(virt);
9333 }
9334
9335 fn unmap_page(virt: u64) {
9336 let pml4_index = (virt >> 39) & 0x1FF;
9337 let pdpt_index = (virt >> 30) & 0x1FF;
9338 let pd_index = (virt >> 21) & 0x1FF;
9339 let pt_index = (virt >> 12) & 0x1FF;
9340
9341 let pml4 = read_cr3() as ptr<u64>;
9342 let pdpt_entry = *(pml4 + pml4_index);
9343
9344 if (pdpt_entry & 1) == 0 { return; }
9345
9346 let pdpt = (pdpt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9347 let pd_entry = *(pdpt + pdpt_index);
9348
9349 if (pd_entry & 1) == 0 { return; }
9350
9351 let pd = (pd_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9352 let pt_entry = *(pd + pd_index);
9353
9354 if (pt_entry & 1) == 0 { return; }
9355
9356 let pt = (pt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9357 *(pt + pt_index) = 0;
9358
9359 tlb_flush_single(virt);
9360 }
9361
9362 struct HeapBlock {
9363 size: u64,
9364 free: u64,
9365 next: u64,
9366 }
9367
9368 let mut heap_start: u64 = 0;
9369 let mut heap_end: u64 = 0;
9370 let mut heap_head: u64 = 0;
9371
9372 fn heap_init(start_addr: u64, initial_size: u64) {
9373 heap_start = start_addr;
9374 heap_end = start_addr + initial_size;
9375
9376 let mut current_addr = heap_start;
9377 while current_addr < heap_end {
9378 let phys = pmm_alloc_page();
9379 map_page(phys, current_addr, 3);
9380 current_addr = current_addr + 4096;
9381 }
9382
9383 heap_head = heap_start;
9384 let first_block = heap_head as ptr<HeapBlock>;
9385 (*first_block).size = initial_size - 24;
9386 (*first_block).free = 1;
9387 (*first_block).next = 0;
9388 }
9389
9390 fn kmalloc(size: u64) -> u64 {
9391 let mut current = heap_head as ptr<HeapBlock>;
9392 let mut best_fit = 0 as ptr<HeapBlock>;
9393
9394 let mut aligned_size = size;
9395 if (aligned_size % 8) != 0 {
9396 aligned_size = aligned_size + (8 - (aligned_size % 8));
9397 }
9398
9399 while (current as u64) != 0 {
9400 if (*current).free == 1 && (*current).size >= aligned_size {
9401 if (best_fit as u64) == 0 {
9402 best_fit = current;
9403 } else {
9404 if (*current).size < (*best_fit).size {
9405 best_fit = current;
9406 }
9407 }
9408 }
9409 current = (*current).next as ptr<HeapBlock>;
9410 }
9411
9412 if (best_fit as u64) != 0 {
9413 let remaining_size = (*best_fit).size - aligned_size;
9414
9415 if remaining_size > 32 {
9416 let new_block_addr = (best_fit as u64) + 24 + aligned_size;
9417 let new_block = new_block_addr as ptr<HeapBlock>;
9418 (*new_block).size = remaining_size - 24;
9419 (*new_block).free = 1;
9420 (*new_block).next = (*best_fit).next;
9421
9422 (*best_fit).size = aligned_size;
9423 (*best_fit).next = new_block_addr;
9424 }
9425
9426 (*best_fit).free = 0;
9427 return (best_fit as u64) + 24;
9428 }
9429
9430 return 0;
9431 }
9432
9433 fn kfree(ptr: u64) {
9434 if ptr == 0 { return; }
9435
9436 let block_addr = ptr - 24;
9437 let block = block_addr as ptr<HeapBlock>;
9438 (*block).free = 1;
9439
9440 let mut current = heap_head as ptr<HeapBlock>;
9441 while (current as u64) != 0 {
9442 if (*current).free == 1 {
9443 let next_addr = (*current).next;
9444 if next_addr != 0 {
9445 let next_block = next_addr as ptr<HeapBlock>;
9446 if (*next_block).free == 1 {
9447 (*current).size = (*current).size + 24 + (*next_block).size;
9448 (*current).next = (*next_block).next;
9449 continue;
9450 }
9451 }
9452 }
9453 current = (*current).next as ptr<HeapBlock>;
9454 }
9455 }
9456
9457 fn wrmsr(msr: u32, val: u64) {
9458 let low = (val & 0xFFFFFFFF) as u32;
9459 let high = (val >> 32) as u32;
9460 asm {
9461 "wrmsr"
9462 :
9463 : "c" (msr), "a" (low), "d" (high)
9464 : "memory"
9465 }
9466 }
9467
9468 fn rdmsr(msr: u32) -> u64 {
9469 let mut low: u32 = 0;
9470 let mut high: u32 = 0;
9471 asm {
9472 "rdmsr"
9473 : "=a" (low), "=d" (high)
9474 : "c" (msr)
9475 }
9476 return ((high as u64) << 32) | (low as u64);
9477 }
9478
9479 fn syscall_init() {
9480 let star_val = (0x08 << 32) | (0x1B << 48);
9481 wrmsr(0xC0000081, star_val);
9482
9483 let lstar_val = syscall_handler_entry as u64;
9484 wrmsr(0xC0000082, lstar_val);
9485
9486 let fmask_val = 0x200;
9487 wrmsr(0xC0000084, fmask_val);
9488
9489 let efer = rdmsr(0xC0000080);
9490 wrmsr(0xC0000080, efer | 1);
9491 }
9492
9493 fn syscall_handler_entry() {
9494 asm {
9495 "swapgs"
9496 "mov gs:[0], rsp"
9497 "mov rsp, gs:[8]"
9498
9499 "push rcx"
9500 "push r11"
9501
9502 "push rdi"
9503 "push rsi"
9504 "push rdx"
9505 "push r10"
9506 "push r8"
9507 "push r9"
9508
9509 "call syscall_dispatcher"
9510
9511 "pop r9"
9512 "pop r8"
9513 "pop r10"
9514 "pop rdx"
9515 "pop rsi"
9516 "pop rdi"
9517
9518 "pop r11"
9519 "pop rcx"
9520
9521 "mov rsp, gs:[0]"
9522 "swapgs"
9523 "sysretq"
9524 }
9525 }
9526
9527 fn syscall_dispatcher(sys_num: u64, arg1: u64, arg2: u64, arg3: u64) -> u64 {
9528 if sys_num == 1 {
9529 return sys_write(arg1, arg2, arg3);
9530 }
9531 if sys_num == 2 {
9532 return sys_read(arg1, arg2, arg3);
9533 }
9534 if sys_num == 3 {
9535 return sys_exit(arg1);
9536 }
9537 if sys_num == 4 {
9538 return sys_mmap(arg1, arg2);
9539 }
9540 return 0;
9541 }
9542
9543 fn sys_write(fd: u64, buf: u64, count: u64) -> u64 {
9544 if fd == 1 {
9545 let mut i: u64 = 0;
9546 let p = buf as ptr<u8>;
9547 while i < count {
9548 panic_put_char(*(p + i), 0x0F, panic_screen_cursor_x, panic_screen_cursor_y);
9549 panic_screen_cursor_x = panic_screen_cursor_x + 1;
9550 if panic_screen_cursor_x >= 80 {
9551 panic_screen_cursor_x = 0;
9552 panic_screen_cursor_y = panic_screen_cursor_y + 1;
9553 }
9554 i = i + 1;
9555 }
9556 return count;
9557 }
9558 return 0;
9559 }
9560
9561 fn sys_read(fd: u64, buf: u64, count: u64) -> u64 {
9562 return 0;
9563 }
9564
9565 fn sys_exit(code: u64) -> u64 {
9566 let curr_pid = current_pid;
9567 let idx = (curr_pid - 1) as usize;
9568 process_table[idx].state = 0;
9569 while true { asm { "hlt" } }
9570 return 0;
9571 }
9572
9573 fn sys_mmap(addr: u64, len: u64) -> u64 {
9574 let pages = len / 4096 + 1;
9575 let mut i: u64 = 0;
9576 while i < pages {
9577 let phys = pmm_alloc_page();
9578 map_page(phys, addr + (i * 4096), 7);
9579 i = i + 1;
9580 }
9581 return addr;
9582 }
9583
9584 fn switch_to_user_mode(entry_point: u64, user_stack: u64) {
9585 asm {
9586 "cli"
9587 "mov ax, 0x23"
9588 "mov ds, ax"
9589 "mov es, ax"
9590 "mov fs, ax"
9591 "mov gs, ax"
9592
9593 "push 0x23"
9594 "push %1"
9595
9596 "push 0x202"
9597
9598 "push 0x1B"
9599 "push %0"
9600
9601 "iretq"
9602 :
9603 : "r" (entry_point), "r" (user_stack)
9604 : "memory"
9605 }
9606 }
9607
9608 fn init_user_process(code_ptr: u64, code_size: u64) {
9609 let user_stack_virt = 0x00007FFFFFFFF000;
9610 let stack_phys = pmm_alloc_page();
9611 map_page(stack_phys, user_stack_virt, 7);
9612
9613 let user_code_virt = 0x0000000000400000;
9614 let code_phys = pmm_alloc_page();
9615 map_page(code_phys, user_code_virt, 7);
9616
9617 let dest = user_code_virt as ptr<u8>;
9618 let src = code_ptr as ptr<u8>;
9619 let mut i: u64 = 0;
9620 while i < code_size {
9621 *(dest + i) = *(src + i);
9622 i = i + 1;
9623 }
9624
9625 switch_to_user_mode(user_code_virt, user_stack_virt + 4096);
9626 }
9627
9628 fn cpuid(leaf: u32, eax: ptr<u32>, ebx: ptr<u32>, ecx: ptr<u32>, edx: ptr<u32>) {
9629 let mut a: u32 = 0;
9630 let mut b: u32 = 0;
9631 let mut c: u32 = 0;
9632 let mut d: u32 = 0;
9633 asm {
9634 "cpuid"
9635 : "=a" (a), "=b" (b), "=c" (c), "=d" (d)
9636 : "a" (leaf)
9637 }
9638 *eax = a;
9639 *ebx = b;
9640 *ecx = c;
9641 *edx = d;
9642 }
9643
9644 fn inb(port: u16) -> u8 {
9645 let mut ret: u8 = 0;
9646 asm {
9647 "in al, dx"
9648 : "=a" (ret)
9649 : "d" (port)
9650 }
9651 return ret;
9652 }
9653
9654 fn io_wait() {
9655 outb(0x80, 0);
9656 }
9657
9658 fn pic_remap(offset1: u8, offset2: u8) {
9659 let a1 = inb(0x21);
9660 let a2 = inb(0xA1);
9661
9662 outb(0x20, 0x11);
9663 io_wait();
9664 outb(0xA0, 0x11);
9665 io_wait();
9666
9667 outb(0x21, offset1);
9668 io_wait();
9669 outb(0xA1, offset2);
9670 io_wait();
9671
9672 outb(0x21, 4);
9673 io_wait();
9674 outb(0xA1, 2);
9675 io_wait();
9676
9677 outb(0x21, 0x01);
9678 io_wait();
9679 outb(0xA1, 0x01);
9680 io_wait();
9681
9682 outb(0x21, a1);
9683 outb(0xA1, a2);
9684 }
9685
9686 fn outl(port: u16, data: u32) {
9687 asm {
9688 "out dx, eax"
9689 :
9690 : "a" (data), "d" (port)
9691 }
9692 }
9693
9694 fn inl(port: u16) -> u32 {
9695 let mut ret: u32 = 0;
9696 asm {
9697 "in eax, dx"
9698 : "=a" (ret)
9699 : "d" (port)
9700 }
9701 return ret;
9702 }
9703
9704 fn outw(port: u16, data: u16) {
9705 asm {
9706 "out dx, ax"
9707 :
9708 : "a" (data), "d" (port)
9709 }
9710 }
9711
9712 fn pci_config_read_word(bus: u8, slot: u8, func: u8, offset: u8) -> u16 {
9713 let lbus = bus as u32;
9714 let lslot = slot as u32;
9715 let lfunc = func as u32;
9716 let tmp = 0x80000000 | (lbus << 16) | (lslot << 11) | (lfunc << 8) | ((offset as u32) & 0xFC);
9717 outl(0xCF8, tmp);
9718 let shift = ((offset & 2) * 8) as u32;
9719 let read_val = inl(0xCFC);
9720 return ((read_val >> shift) & 0xFFFF) as u16;
9721 }
9722
9723 fn pci_config_read_dword(bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
9724 let lbus = bus as u32;
9725 let lslot = slot as u32;
9726 let lfunc = func as u32;
9727 let tmp = 0x80000000 | (lbus << 16) | (lslot << 11) | (lfunc << 8) | ((offset as u32) & 0xFC);
9728 outl(0xCF8, tmp);
9729 return inl(0xCFC);
9730 }
9731
9732 fn pci_check_vendor(bus: u8, slot: u8) -> u16 {
9733 return pci_config_read_word(bus, slot, 0, 0);
9734 }
9735
9736 struct PciDevice {
9737 bus: u8,
9738 slot: u8,
9739 func: u8,
9740 vendor_id: u16,
9741 device_id: u16,
9742 class_id: u8,
9743 subclass_id: u8,
9744 prog_if: u8,
9745 rev_id: u8,
9746 bar0: u32,
9747 bar1: u32,
9748 bar2: u32,
9749 bar3: u32,
9750 bar4: u32,
9751 bar5: u32,
9752 }
9753
9754 let mut pci_device_list: [PciDevice; 256];
9755 let mut pci_device_count: u64 = 0;
9756
9757 fn pci_add_device(bus: u8, slot: u8, func: u8) {
9758 if pci_device_count >= 256 { return; }
9759 let vendor = pci_config_read_word(bus, slot, func, 0);
9760 if vendor == 0xFFFF { return; }
9761
9762 let device = pci_config_read_word(bus, slot, func, 2);
9763 let class_word = pci_config_read_word(bus, slot, func, 0x0A);
9764 let class_id = (class_word >> 8) as u8;
9765 let subclass_id = (class_word & 0xFF) as u8;
9766
9767 let prog_word = pci_config_read_word(bus, slot, func, 0x08);
9768 let prog_if = (prog_word >> 8) as u8;
9769 let rev_id = (prog_word & 0xFF) as u8;
9770
9771 let b0 = pci_config_read_dword(bus, slot, func, 0x10);
9772 let b1 = pci_config_read_dword(bus, slot, func, 0x14);
9773 let b2 = pci_config_read_dword(bus, slot, func, 0x18);
9774 let b3 = pci_config_read_dword(bus, slot, func, 0x1C);
9775 let b4 = pci_config_read_dword(bus, slot, func, 0x20);
9776 let b5 = pci_config_read_dword(bus, slot, func, 0x24);
9777
9778 let idx = pci_device_count as usize;
9779 pci_device_list[idx].bus = bus;
9780 pci_device_list[idx].slot = slot;
9781 pci_device_list[idx].func = func;
9782 pci_device_list[idx].vendor_id = vendor;
9783 pci_device_list[idx].device_id = device;
9784 pci_device_list[idx].class_id = class_id;
9785 pci_device_list[idx].subclass_id = subclass_id;
9786 pci_device_list[idx].prog_if = prog_if;
9787 pci_device_list[idx].rev_id = rev_id;
9788 pci_device_list[idx].bar0 = b0;
9789 pci_device_list[idx].bar1 = b1;
9790 pci_device_list[idx].bar2 = b2;
9791 pci_device_list[idx].bar3 = b3;
9792 pci_device_list[idx].bar4 = b4;
9793 pci_device_list[idx].bar5 = b5;
9794
9795 pci_device_count = pci_device_count + 1;
9796 }
9797
9798 fn pci_scan_bus() {
9799 let mut bus: u64 = 0;
9800 while bus < 256 {
9801 let mut slot: u64 = 0;
9802 while slot < 32 {
9803 let vendor = pci_check_vendor(bus as u8, slot as u8);
9804 if vendor != 0xFFFF {
9805 let mut func: u64 = 0;
9806 while func < 8 {
9807 let f_vendor = pci_config_read_word(bus as u8, slot as u8, func as u8, 0);
9808 if f_vendor != 0xFFFF {
9809 pci_add_device(bus as u8, slot as u8, func as u8);
9810 }
9811 func = func + 1;
9812 }
9813 }
9814 slot = slot + 1;
9815 }
9816 bus = bus + 1;
9817 }
9818 }
9819
9820 struct VfsNode {
9821 name: [u8; 64],
9822 inode: u64,
9823 size: u64,
9824 flags: u32,
9825 uid: u32,
9826 gid: u32,
9827 read_ptr: u64,
9828 write_ptr: u64,
9829 open_ptr: u64,
9830 close_ptr: u64,
9831 read_dir_ptr: u64,
9832 find_dir_ptr: u64,
9833 parent: u64,
9834 sibling: u64,
9835 child: u64,
9836 }
9837
9838 let mut vfs_nodes: [VfsNode; 1024];
9839 let mut vfs_node_count: u64 = 0;
9840 let mut vfs_root: u64 = 0;
9841
9842 fn vfs_init() {
9843 vfs_node_count = 1;
9844 vfs_root = 0;
9845 let root_idx = vfs_root as usize;
9846 vfs_nodes[root_idx].name[0] = 47;
9847 vfs_nodes[root_idx].name[1] = 0;
9848 vfs_nodes[root_idx].inode = 0;
9849 vfs_nodes[root_idx].size = 0;
9850 vfs_nodes[root_idx].flags = 2;
9851 vfs_nodes[root_idx].parent = 0;
9852 vfs_nodes[root_idx].sibling = 0;
9853 vfs_nodes[root_idx].child = 0;
9854 }
9855
9856 fn strcmp(s1: ptr<u8>, s2: ptr<u8>) -> u64 {
9857 let mut i: u64 = 0;
9858 while *(s1 + i) != 0 && *(s2 + i) != 0 {
9859 if *(s1 + i) != *(s2 + i) {
9860 return 1;
9861 }
9862 i = i + 1;
9863 }
9864 if *(s1 + i) != *(s2 + i) {
9865 return 1;
9866 }
9867 return 0;
9868 }
9869
9870 fn strcpy(dest: ptr<u8>, src: ptr<u8>) {
9871 let mut i: u64 = 0;
9872 while *(src + i) != 0 {
9873 *(dest + i) = *(src + i);
9874 i = i + 1;
9875 }
9876 *(dest + i) = 0;
9877 }
9878
9879 fn vfs_create_file(parent_idx: u64, name: ptr<u8>, is_dir: u8) -> u64 {
9880 if vfs_node_count >= 1024 { return 0xFFFFFFFF; }
9881
9882 let new_idx = vfs_node_count;
9883 let n_idx = new_idx as usize;
9884 let p_idx = parent_idx as usize;
9885
9886 strcpy(&vfs_nodes[n_idx].name[0] as ptr<u8>, name);
9887 vfs_nodes[n_idx].inode = new_idx;
9888 vfs_nodes[n_idx].size = 0;
9889 if is_dir == 1 {
9890 vfs_nodes[n_idx].flags = 2;
9891 } else {
9892 vfs_nodes[n_idx].flags = 1;
9893 }
9894 vfs_nodes[n_idx].parent = parent_idx;
9895 vfs_nodes[n_idx].sibling = vfs_nodes[p_idx].child;
9896 vfs_nodes[n_idx].child = 0;
9897
9898 vfs_nodes[p_idx].child = new_idx;
9899 vfs_node_count = vfs_node_count + 1;
9900
9901 return new_idx;
9902 }
9903
9904 fn vfs_find_child(parent_idx: u64, name: ptr<u8>) -> u64 {
9905 let p_idx = parent_idx as usize;
9906 let mut curr_idx = vfs_nodes[p_idx].child;
9907
9908 while curr_idx != 0 {
9909 let c_idx = curr_idx as usize;
9910 if strcmp(&vfs_nodes[c_idx].name[0] as ptr<u8>, name) == 0 {
9911 return curr_idx;
9912 }
9913 curr_idx = vfs_nodes[c_idx].sibling;
9914 }
9915 return 0xFFFFFFFF;
9916 }
9917
9918 struct FileDescriptor {
9919 node_idx: u64,
9920 offset: u64,
9921 flags: u32,
9922 used: u8,
9923 }
9924
9925 let mut fd_table: [FileDescriptor; 256];
9926
9927 fn fd_init() {
9928 let mut i: u64 = 0;
9929 while i < 256 {
9930 fd_table[i as usize].used = 0;
9931 i = i + 1;
9932 }
9933 }
9934
9935 fn sys_open(path: ptr<u8>, flags: u32) -> u64 {
9936 let mut i: u64 = 0;
9937 let mut fd_idx: u64 = 0xFFFFFFFF;
9938 while i < 256 {
9939 if fd_table[i as usize].used == 0 {
9940 fd_idx = i;
9941 break;
9942 }
9943 i = i + 1;
9944 }
9945 if fd_idx == 0xFFFFFFFF { return 0xFFFFFFFF; }
9946
9947 let node_idx = vfs_find_child(vfs_root, path);
9948 if node_idx == 0xFFFFFFFF {
9949 if (flags & 0x40) != 0 {
9950 let new_node = vfs_create_file(vfs_root, path, 0);
9951 if new_node == 0xFFFFFFFF { return 0xFFFFFFFF; }
9952 fd_table[fd_idx as usize].node_idx = new_node;
9953 fd_table[fd_idx as usize].offset = 0;
9954 fd_table[fd_idx as usize].flags = flags;
9955 fd_table[fd_idx as usize].used = 1;
9956 return fd_idx;
9957 }
9958 return 0xFFFFFFFF;
9959 }
9960
9961 fd_table[fd_idx as usize].node_idx = node_idx;
9962 fd_table[fd_idx as usize].offset = 0;
9963 fd_table[fd_idx as usize].flags = flags;
9964 fd_table[fd_idx as usize].used = 1;
9965 return fd_idx;
9966 }
9967
9968 struct AhciHbaPort {
9969 clb: u32,
9970 clbu: u32,
9971 fb: u32,
9972 fbu: u32,
9973 is: u32,
9974 ie: u32,
9975 cmd: u32,
9976 rsv0: u32,
9977 tfd: u32,
9978 sig: u32,
9979 ssts: u32,
9980 sctl: u32,
9981 serr: u32,
9982 sact: u32,
9983 ci: u32,
9984 sntf: u32,
9985 fbs: u32,
9986 rsv1: [u32; 11],
9987 vendor: [u32; 4],
9988 }
9989
9990 struct AhciHbaMem {
9991 cap: u32,
9992 ghc: u32,
9993 is: u32,
9994 pi: u32,
9995 vs: u32,
9996 ccc_ctl: u32,
9997 ccc_pts: u32,
9998 em_loc: u32,
9999 em_ctl: u32,
10000 cap2: u32,
10001 bohc: u32,
10002 rsv: [u8; 116],
10003 vendor: [u8; 96],
10004 ports: [AhciHbaPort; 32],
10005 }
10006
10007 fn ahci_check_type(port: ptr<AhciHbaPort>) -> u32 {
10008 let ssts = (*port).ssts;
10009 let ipm = (ssts >> 8) & 0x0F;
10010 let det = ssts & 0x0F;
10011 if det != 3 { return 0; }
10012 if ipm != 1 { return 0; }
10013 let sig = (*port).sig;
10014 if sig == 0x00000101 { return 1; }
10015 if sig == 0xEB140101 { return 2; }
10016 if sig == 0x96690101 { return 3; }
10017 if sig == 0xC33C0101 { return 4; }
10018 return 0;
10019 }
10020
10021 let mut ahci_base_address: u64 = 0;
10022
10023 fn ahci_init(pci_bus: u8, pci_slot: u8, pci_func: u8) {
10024 let bar5_val = pci_config_read_dword(pci_bus, pci_slot, pci_func, 0x24);
10025 ahci_base_address = (bar5_val & 0xFFFFFFF0) as u64;
10026 let hba = ahci_base_address as ptr<AhciHbaMem>;
10027 let pi = (*hba).pi;
10028 let mut i: u32 = 0;
10029 while i < 32 {
10030 if (pi & (1 << i)) != 0 {
10031 let port_ptr = &(*hba).ports[i as usize] as ptr<AhciHbaPort>;
10032 let ptype = ahci_check_type(port_ptr);
10033 }
10034 i = i + 1;
10035 }
10036 }
10037
10038 fn rtl8139_init(bus: u8, slot: u8, func: u8) {
10039 let bar0 = pci_config_read_dword(bus, slot, func, 0x10);
10040 let io_base = (bar0 & 0xFFFFFFFC) as u16;
10041 outb(io_base + 0x52, 0x00);
10042 outb(io_base + 0x37, 0x10);
10043 let mut i: u16 = 0;
10044 while i < 1000 {
10045 if (inb(io_base + 0x37) & 0x10) == 0 {
10046 break;
10047 }
10048 i = i + 1;
10049 }
10050 let rx_buffer = pmm_alloc_page();
10051 let rx_buffer_phys = rx_buffer & 0xFFFFFFFF;
10052 outl(io_base + 0x30, rx_buffer_phys as u32);
10053 outw(io_base + 0x3C, 0x0005);
10054 outl(io_base + 0x44, 0x0000000F | 0x00000080);
10055 outb(io_base + 0x37, 0x0C);
10056 }
10057
10058 fn pci_driver_match() {
10059 let mut i: u64 = 0;
10060 while i < pci_device_count {
10061 let dev = &pci_device_list[i as usize] as ptr<PciDevice>;
10062 if (*dev).class_id == 0x01 && (*dev).subclass_id == 0x06 {
10063 if (*dev).prog_if == 0x01 {
10064 ahci_init((*dev).bus, (*dev).slot, (*dev).func);
10065 }
10066 }
10067 if (*dev).vendor_id == 0x10EC && (*dev).device_id == 0x8139 {
10068 rtl8139_init((*dev).bus, (*dev).slot, (*dev).func);
10069 }
10070 i = i + 1;
10071 }
10072 }
10073
10074 let keymap_lower: [u8; 128] = [
10075 0, 27, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 8,
10076 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 91, 93, 10,
10077 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59, 39, 96,
10078 0, 92, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0,
10079 42, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10080 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0,
10081 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10082 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
10083 ];
10084
10085 let keymap_upper: [u8; 128] = [
10086 0, 27, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 8,
10087 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 123, 125, 10,
10088 0, 65, 83, 68, 70, 71, 72, 74, 75, 76, 58, 34, 126,
10089 0, 124, 90, 88, 67, 86, 66, 78, 77, 60, 62, 63, 0,
10090 42, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10091 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0,
10092 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10093 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
10094 ];
10095
10096 let mut kbd_shift_active: u8 = 0;
10097 let mut kbd_caps_active: u8 = 0;
10098
10099 let mut shell_buffer: [u8; 256];
10100 let mut shell_idx: u64 = 0;
10101 let mut shell_active: u8 = 0;
10102
10103 fn kbd_init() {
10104 let mut status = inb(0x64);
10105 while (status & 2) != 0 {
10106 status = inb(0x64);
10107 }
10108 outb(0x64, 0xAD);
10109 outb(0x64, 0xA7);
10110 let temp = inb(0x60);
10111 outb(0x64, 0xAE);
10112 }
10113
10114 fn kbd_handler(state: ptr<CpuState>) {
10115 let status = inb(0x64);
10116 if (status & 1) != 0 {
10117 let scancode = inb(0x60);
10118
10119 if scancode == 0x2A || scancode == 0x36 {
10120 kbd_shift_active = 1;
10121 } else if scancode == 0xAA || scancode == 0xB6 {
10122 kbd_shift_active = 0;
10123 } else if scancode == 0x3A {
10124 if kbd_caps_active == 0 {
10125 kbd_caps_active = 1;
10126 } else {
10127 kbd_caps_active = 0;
10128 }
10129 } else if (scancode & 0x80) == 0 {
10130 let mut ascii: u8 = 0;
10131 let mut use_upper = kbd_shift_active;
10132
10133 if kbd_caps_active == 1 {
10134 let base_char = keymap_lower[scancode as usize];
10135 if base_char >= 97 && base_char <= 122 {
10136 if kbd_shift_active == 1 {
10137 use_upper = 0;
10138 } else {
10139 use_upper = 1;
10140 }
10141 }
10142 }
10143
10144 if use_upper == 1 {
10145 ascii = keymap_upper[scancode as usize];
10146 } else {
10147 ascii = keymap_lower[scancode as usize];
10148 }
10149
10150 if ascii != 0 && shell_active == 1 {
10151 shell_process_key(ascii);
10152 }
10153 }
10154 }
10155 outb(0x20, 0x20);
10156 }
10157
10158 fn shell_print_prompt() {
10159 panic_print_string("root@w-os # " as ptr<u8>, 0x0A);
10160 }
10161
10162 fn shell_init() {
10163 shell_idx = 0;
10164 shell_active = 1;
10165 let mut i: u64 = 0;
10166 while i < 256 {
10167 shell_buffer[i as usize] = 0;
10168 i = i + 1;
10169 }
10170 panic_clear_screen(0x0F);
10171 panic_print_string("W Operating System - Core Shell\n" as ptr<u8>, 0x0B);
10172 panic_print_string("Type 'help' for a list of commands.\n\n" as ptr<u8>, 0x07);
10173 shell_print_prompt();
10174 }
10175
10176 fn shell_execute() {
10177 panic_print_string("\n" as ptr<u8>, 0x07);
10178 if shell_idx == 0 {
10179 shell_print_prompt();
10180 return;
10181 }
10182
10183 shell_buffer[shell_idx as usize] = 0;
10184 let cmd_ptr = &shell_buffer[0] as ptr<u8>;
10185
10186 if strcmp(cmd_ptr, "help" as ptr<u8>) == 0 {
10187 panic_print_string("Available commands:\n" as ptr<u8>, 0x0F);
10188 panic_print_string(" help - Show this message\n" as ptr<u8>, 0x07);
10189 panic_print_string(" clear - Clear the screen\n" as ptr<u8>, 0x07);
10190 panic_print_string(" uname - Show system information\n" as ptr<u8>, 0x07);
10191 panic_print_string(" lspci - List PCI devices\n" as ptr<u8>, 0x07);
10192 } else if strcmp(cmd_ptr, "clear" as ptr<u8>) == 0 {
10193 panic_clear_screen(0x0F);
10194 } else if strcmp(cmd_ptr, "uname" as ptr<u8>) == 0 {
10195 panic_print_string("W Kernel 0.0.1 beta - x86_64\n" as ptr<u8>, 0x0E);
10196 } else if strcmp(cmd_ptr, "lspci" as ptr<u8>) == 0 {
10197 let mut i: u64 = 0;
10198 while i < pci_device_count {
10199 let dev = &pci_device_list[i as usize] as ptr<PciDevice>;
10200 panic_print_string("Bus " as ptr<u8>, 0x07);
10201 panic_print_hex((*dev).bus as u64, 0x07);
10202 panic_print_string(" Slot " as ptr<u8>, 0x07);
10203 panic_print_hex((*dev).slot as u64, 0x07);
10204 panic_print_string(" - Vendor: " as ptr<u8>, 0x07);
10205 panic_print_hex((*dev).vendor_id as u64, 0x0A);
10206 panic_print_string(" Device: " as ptr<u8>, 0x07);
10207 panic_print_hex((*dev).device_id as u64, 0x0B);
10208 panic_print_string("\n" as ptr<u8>, 0x07);
10209 i = i + 1;
10210 }
10211 } else {
10212 panic_print_string("Unknown command: " as ptr<u8>, 0x0C);
10213 panic_print_string(cmd_ptr, 0x0C);
10214 panic_print_string("\n" as ptr<u8>, 0x07);
10215 }
10216
10217 shell_idx = 0;
10218 shell_print_prompt();
10219 }
10220
10221 fn shell_process_key(c: u8) {
10222 if c == 10 {
10223 shell_execute();
10224 } else if c == 8 {
10225 if shell_idx > 0 {
10226 shell_idx = shell_idx - 1;
10227 shell_buffer[shell_idx as usize] = 0;
10228 if panic_screen_cursor_x > 0 {
10229 panic_screen_cursor_x = panic_screen_cursor_x - 1;
10230 } else if panic_screen_cursor_y > 0 {
10231 panic_screen_cursor_y = panic_screen_cursor_y - 1;
10232 panic_screen_cursor_x = 79;
10233 }
10234 panic_put_char(32, 0x0F, panic_screen_cursor_x, panic_screen_cursor_y);
10235 }
10236 } else {
10237 if shell_idx < 255 {
10238 shell_buffer[shell_idx as usize] = c;
10239 shell_idx = shell_idx + 1;
10240 let mut color_code: u8 = 0x0F;
10241 panic_put_char(c, color_code, panic_screen_cursor_x, panic_screen_cursor_y);
10242 panic_screen_cursor_x = panic_screen_cursor_x + 1;
10243 if panic_screen_cursor_x >= 80 {
10244 panic_screen_cursor_x = 0;
10245 panic_screen_cursor_y = panic_screen_cursor_y + 1;
10246 if panic_screen_cursor_y >= 25 {
10247 panic_screen_cursor_y = 24;
10248 }
10249 }
10250 }
10251 }
10252 }
10253
10254 struct BootSectorFat32 {
10255 jmp: [u8; 3],
10256 oem_name: [u8; 8],
10257 bytes_per_sector: u16,
10258 sectors_per_cluster: u8,
10259 reserved_sectors: u16,
10260 fat_count: u8,
10261 root_dir_entries: u16,
10262 total_sectors_16: u16,
10263 media_descriptor: u8,
10264 sectors_per_fat_16: u16,
10265 sectors_per_track: u16,
10266 head_count: u16,
10267 hidden_sectors: u32,
10268 total_sectors_32: u32,
10269 sectors_per_fat_32: u32,
10270 ext_flags: u16,
10271 fs_version: u16,
10272 root_cluster: u32,
10273 fs_info_sector: u16,
10274 backup_boot_sector: u16,
10275 reserved: [u8; 12],
10276 drive_number: u8,
10277 reserved1: u8,
10278 boot_signature: u8,
10279 volume_id: u32,
10280 volume_label: [u8; 11],
10281 fs_type: [u8; 8],
10282 }
10283
10284 struct Fat32DirEntry {
10285 name: [u8; 11],
10286 attr: u8,
10287 nt_res: u8,
10288 crt_time_tenth: u8,
10289 crt_time: u16,
10290 crt_date: u16,
10291 last_access_date: u16,
10292 cluster_high: u16,
10293 write_time: u16,
10294 write_date: u16,
10295 cluster_low: u16,
10296 file_size: u32,
10297 }
10298
10299 let mut fat32_lba_start: u32 = 0;
10300 let mut fat32_root_cluster: u32 = 0;
10301 let mut fat32_sectors_per_cluster: u32 = 0;
10302 let mut fat32_bytes_per_cluster: u32 = 0;
10303 let mut fat32_fat_start: u32 = 0;
10304 let mut fat32_data_start: u32 = 0;
10305
10306 fn fat32_init(lba: u32, buffer: ptr<u8>) {
10307 let bs = buffer as ptr<BootSectorFat32>;
10308 fat32_lba_start = lba;
10309 fat32_sectors_per_cluster = (*bs).sectors_per_cluster as u32;
10310 fat32_bytes_per_cluster = fat32_sectors_per_cluster * ((*bs).bytes_per_sector as u32);
10311 fat32_fat_start = lba + ((*bs).reserved_sectors as u32);
10312 let fat_size = (*bs).sectors_per_fat_32;
10313 let fat_count = (*bs).fat_count as u32;
10314 fat32_data_start = fat32_fat_start + (fat_size * fat_count);
10315 fat32_root_cluster = (*bs).root_cluster;
10316 }
10317
10318 fn fat32_cluster_to_lba(cluster: u32) -> u32 {
10319 if cluster < 2 { return 0; }
10320 return fat32_data_start + ((cluster - 2) * fat32_sectors_per_cluster);
10321 }
10322
10323 fn fat32_compare_name(entry_name: ptr<u8>, target: ptr<u8>) -> u32 {
10324 let mut i: u64 = 0;
10325 while i < 11 {
10326 if *(target + i) == 0 {
10327 if *(entry_name + i) == 32 {
10328 let mut j = i;
10329 let mut all_space = 1;
10330 while j < 11 {
10331 if *(entry_name + j) != 32 {
10332 all_space = 0;
10333 break;
10334 }
10335 j = j + 1;
10336 }
10337 if all_space == 1 { return 1; }
10338 }
10339 return 0;
10340 }
10341 if *(entry_name + i) != *(target + i) {
10342 return 0;
10343 }
10344 i = i + 1;
10345 }
10346 if *(target + 11) == 0 { return 1; }
10347 return 0;
10348 }
10349
10350 struct WefHeader {
10351 magic: u32,
10352 arch: u8,
10353 os_abi: u8,
10354 type_id: u16,
10355 machine: u16,
10356 version: u32,
10357 entry: u64,
10358 ph_off: u64,
10359 sh_off: u64,
10360 flags: u32,
10361 eh_size: u16,
10362 ph_ent_size: u16,
10363 ph_num: u16,
10364 sh_ent_size: u16,
10365 sh_num: u16,
10366 sh_str_ndx: u16,
10367 }
10368
10369 struct WefProgramHeader {
10370 type_id: u32,
10371 flags: u32,
10372 offset: u64,
10373 vaddr: u64,
10374 paddr: u64,
10375 filesz: u64,
10376 memsz: u64,
10377 align: u64,
10378 }
10379
10380 fn wef_check_magic(header: ptr<WefHeader>) -> u32 {
10381 let m = (*header).magic;
10382 if m == 0x4645577F {
10383 return 1;
10384 }
10385 return 0;
10386 }
10387
10388 fn sys_yield() {
10389 asm {
10390 "int 0x20"
10391 }
10392 }
10393
10394 fn sys_wait_pid(pid: u64) {
10395 let mut status: u8 = 1;
10396 while status == 1 {
10397 let mut i: u64 = 0;
10398 let mut found = 0;
10399 while i < 256 {
10400 if process_table[i as usize].pid == pid {
10401 status = process_table[i as usize].state;
10402 found = 1;
10403 break;
10404 }
10405 i = i + 1;
10406 }
10407 if found == 0 { break; }
10408 sys_yield();
10409 }
10410 }
10411
10412 fn wef_load_segment(ph: ptr<WefProgramHeader>, file_base: u64, cr3_val: u64) {
10413 if (*ph).type_id != 1 { return; }
10414 if (*ph).memsz == 0 { return; }
10415
10416 let vaddr_start = (*ph).vaddr;
10417 let memsz = (*ph).memsz;
10418 let filesz = (*ph).filesz;
10419 let offset = (*ph).offset;
10420
10421 let page_count = (memsz + 4095) / 4096;
10422 let mut i: u64 = 0;
10423
10424 let current_cr3 = read_cr3();
10425 write_cr3(cr3_val);
10426
10427 while i < page_count {
10428 let phys_page = pmm_alloc_page();
10429 let virt_page = (vaddr_start & 0xFFFFFFFFFFFFF000) + (i * 4096);
10430 let mut flags: u64 = 5;
10431 if ((*ph).flags & 2) != 0 {
10432 flags = flags | 2;
10433 }
10434 map_page(phys_page, virt_page, flags);
10435 i = i + 1;
10436 }
10437
10438 let dest = vaddr_start as ptr<u8>;
10439 let src = (file_base + offset) as ptr<u8>;
10440
10441 let mut j: u64 = 0;
10442 while j < filesz {
10443 *(dest + j) = *(src + j);
10444 j = j + 1;
10445 }
10446
10447 while j < memsz {
10448 *(dest + j) = 0;
10449 j = j + 1;
10450 }
10451
10452 write_cr3(current_cr3);
10453 }
10454
10455 fn process_exec_wef(file_buffer: u64) -> u64 {
10456 let header = file_buffer as ptr<WefHeader>;
10457 if wef_check_magic(header) == 0 {
10458 return 0;
10459 }
10460
10461 let pml4_phys = pmm_alloc_page();
10462
10463 let kernel_pml4 = read_cr3() as ptr<u64>;
10464 let new_pml4 = pml4_phys as ptr<u64>;
10465
10466 let mut idx: u64 = 256;
10467 while idx < 512 {
10468 *(new_pml4 + idx) = *(kernel_pml4 + idx);
10469 idx = idx + 1;
10470 }
10471
10472 let ph_base = file_buffer + (*header).ph_off;
10473 let ph_count = (*header).ph_num as u64;
10474 let ph_size = (*header).ph_ent_size as u64;
10475
10476 let mut i: u64 = 0;
10477 while i < ph_count {
10478 let ph_ptr = (ph_base + (i * ph_size)) as ptr<WefProgramHeader>;
10479 wef_load_segment(ph_ptr, file_buffer, pml4_phys);
10480 i = i + 1;
10481 }
10482
10483 let user_stack_virt = 0x00007FFFFFFFF000;
10484 let stack_phys = pmm_alloc_page();
10485
10486 let current_cr3 = read_cr3();
10487 write_cr3(pml4_phys);
10488 map_page(stack_phys, user_stack_virt, 7);
10489 write_cr3(current_cr3);
10490
10491 let entry_point = (*header).entry;
10492 let new_pid = process_create(entry_point, user_stack_virt + 4096, pml4_phys);
10493
10494 return new_pid;
10495 }
10496
10497 fn sys_exec(path_ptr: u64) -> u64 {
10498 return 0;
10499 }
10500
10501 fn sys_fork() -> u64 {
10502 let curr_pid = current_pid;
10503 if curr_pid == 0 { return 0; }
10504
10505 let parent_idx = (curr_pid - 1) as usize;
10506 let parent_cr3 = process_table[parent_idx].cr3;
10507
10508 let child_cr3 = pmm_alloc_page();
10509 let p_pml4 = parent_cr3 as ptr<u64>;
10510 let c_pml4 = child_cr3 as ptr<u64>;
10511
10512 let mut i: u64 = 256;
10513 while i < 512 {
10514 *(c_pml4 + i) = *(p_pml4 + i);
10515 i = i + 1;
10516 }
10517
10518 let child_pid = process_create(
10519 process_table[parent_idx].rip,
10520 process_table[parent_idx].rsp,
10521 child_cr3
10522 );
10523
10524 return child_pid;
10525 }
10526
10527 fn kthread_create(entry: u64, stack_size: u64) -> u64 {
10528 let stack_base = kmalloc(stack_size);
10529 let stack_top = stack_base + stack_size;
10530 let cr3 = read_cr3();
10531
10532 let pid = process_create(entry, stack_top, cr3);
10533 let idx = (pid - 1) as usize;
10534 process_table[idx].state = 2;
10535
10536 return pid;
10537 }
10538
10539 let mut uptime_seconds: u64 = 0;
10540 let mut uptime_ms: u64 = 0;
10541
10542 fn rtc_read(reg: u8) -> u8 {
10543 outb(0x70, reg);
10544 return inb(0x71);
10545 }
10546
10547 fn timer_update_uptime() {
10548 uptime_ms = uptime_ms + 1;
10549 if uptime_ms >= 1000 {
10550 uptime_ms = 0;
10551 uptime_seconds = uptime_seconds + 1;
10552 }
10553 }

« Tüm Sürümlere Dön