Wux Maskot

W OPERATING SYSTEM

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

Kuruluş Amblemi

SÜRÜM DETAYI: 1.0.0 Beta

Yayın Tarihi: 2026-10-18

Yama Notları:

Terminal eklenmiştir. Bellek krizi fixlenmişir. 32 bitten 64 bite geçiş esnasında çıkan sorunlar giderilmiştir.

Ç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.2 betal" as ptr<u8>;
15 const MB2_MAGIC: u32 = 0xE85250D6;
16 const ARCH_X86_64: u32 = 0;
17
18 struct MB2Header {
19 magic: u32,
20 arch: u32,
21 length: u32,
22 checksum: u32,
23 }
24
25 const HEADER: MB2Header = MB2Header {
26 magic: MB2_MAGIC,
27 arch: ARCH_X86_64,
28 length: 16,
29 checksum: (0u32 - (MB2_MAGIC + ARCH_X86_64 + 16)),
30 };
31
32 // --- Port I/O ve Temel CPU Komutları ---
33 fn outb(port: u16, data: u8) {
34 asm { "out dx, al" in dx = port; in al = data; }
35 }
36 fn outw(port: u16, data: u16) {
37 asm { "out dx, ax" in dx = port; in ax = data; }
38 }
39 fn outl(port: u16, data: u32) {
40 asm { "out dx, eax" in dx = port; in eax = data; }
41 }
42 fn inb(port: u16) -> u8 {
43 let mut data: u8;
44 asm { "in al, dx" in dx = port; out al = data; }
45 return data;
46 }
47 fn inw(port: u16) -> u16 {
48 let mut data: u16;
49 asm { "in ax, dx" in dx = port; out ax = data; }
50 return data;
51 }
52 fn inl(port: u16) -> u32 {
53 let mut data: u32;
54 asm { "in eax, dx" in dx = port; out eax = data; }
55 return data;
56 }
57 fn cpu_hlt() { asm { "hlt" } }
58 fn cpu_cli() { asm { "cli" } }
59 fn cpu_sti() { asm { "sti" } }
60 fn cpu_pause() { asm { "pause" } }
61
62 fn invlpg(addr: u64) {
63 asm { "invlpg [rax]" in rax = addr; }
64 }
65 fn wbinvd() { asm { "wbinvd" } }
66
67 fn cpuid(leaf: u32, subleaf: u32, eax: ptr<u32>, ebx: ptr<u32>, ecx: ptr<u32>, edx: ptr<u32>) {
68 let mut o_eax: u32;
69 let mut o_ebx: u32;
70 let mut o_ecx: u32;
71 let mut o_edx: u32;
72 asm {
73 "cpuid"
74 in eax = leaf;
75 in ecx = subleaf;
76 out eax = o_eax;
77 out ebx = o_ebx;
78 out ecx = o_ecx;
79 out edx = o_edx;
80 }
81 *eax = o_eax;
82 *ebx = o_ebx;
83 *ecx = o_ecx;
84 *edx = o_edx;
85 }
86
87 fn rdmsr(msr: u32) -> u64 {
88 let mut lo: u32;
89 let mut hi: u32;
90 asm {
91 "rdmsr"
92 in ecx = msr;
93 out eax = lo;
94 out edx = hi;
95 }
96 return (hi as u64 << 32) | (lo as u64);
97 }
98
99 fn wrmsr(msr: u32, val: u64) {
100 let lo = (val & 0xFFFFFFFF) as u32;
101 let hi = (val >> 32) as u32;
102 asm {
103 "wrmsr"
104 in ecx = msr;
105 in eax = lo;
106 in edx = hi;
107 }
108 }
109
110 // --- Senkronizasyon (Spinlock) ---
111 struct Spinlock {
112 locked: u32,
113 }
114
115 fn spin_init(lock: ptr<Spinlock>) {
116 (*lock).locked = 0;
117 }
118
119 fn spin_lock(lock: ptr<Spinlock>) {
120 let mut success: u8 = 0;
121 while success == 0 {
122 asm {
123 "lock bts dword [rdi], 0\n"
124 "setnc al"
125 in rdi = lock;
126 out al = success;
127 }
128 if success == 0 {
129 cpu_pause();
130 }
131 }
132 }
133
134 fn spin_trylock(lock: ptr<Spinlock>) -> u8 {
135 let mut success: u8 = 0;
136 asm {
137 "lock bts dword [rdi], 0\n"
138 "setnc al"
139 in rdi = lock;
140 out al = success;
141 }
142 return success;
143 }
144
145 fn spin_unlock(lock: ptr<Spinlock>) {
146 asm {
147 "lock btr dword [rdi], 0"
148 in rdi = lock;
149 }
150 }
151
152 // --- Bellek İşlemleri ---
153 fn memcpy(dest: ptr<u8>, src: ptr<u8>, n: u64) {
154 let mut d = dest as ptr<u64>;
155 let mut s = src as ptr<u64>;
156 let len = n / 8;
157 for i in 0..len {
158 *(d + i) = *(s + i);
159 }
160 let rem = n % 8;
161 let d8 = (dest as u64 + len * 8) as ptr<u8>;
162 let s8 = (src as u64 + len * 8) as ptr<u8>;
163 for i in 0..rem {
164 *(d8 + i) = *(s8 + i);
165 }
166 }
167
168 fn memset(dest: ptr<u8>, val: u8, n: u64) {
169 let v8 = val as u64;
170 let v64 = v8 | (v8 << 8) | (v8 << 16) | (v8 << 24) | (v8 << 32) | (v8 << 40) | (v8 << 48) | (v8 << 56);
171 let mut d = dest as ptr<u64>;
172 let len = n / 8;
173 for i in 0..len {
174 *(d + i) = v64;
175 }
176 let rem = n % 8;
177 let d8 = (dest as u64 + len * 8) as ptr<u8>;
178 for i in 0..rem {
179 *(d8 + i) = val;
180 }
181 }
182
183 fn memcmp(p1: ptr<u8>, p2: ptr<u8>, n: u64) -> i32 {
184 for i in 0..n {
185 let diff = (*(p1 + i) as i32) - (*(p2 + i) as i32);
186 if diff != 0 {
187 return diff;
188 }
189 }
190 return 0;
191 }
192
193 fn memmove(dest: ptr<u8>, src: ptr<u8>, n: u64) {
194 if (dest as u64) < (src as u64) {
195 memcpy(dest, src, n);
196 } else {
197 for i in (0..n).rev() {
198 *(dest + i) = *(src + i);
199 }
200 }
201 }
202
203 // --- GDT & TSS (Long Mode Uyumlu 16-Bayt TSS) ---
204 struct GDTEntry {
205 limit_low: u16,
206 base_low: u16,
207 base_mid: u8,
208 access: u8,
209 flags_limit: u8,
210 base_hi: u8,
211 }
212
213 struct TSSEntry {
214 rsv0: u32,
215 rsp0: u64,
216 rsp1: u64,
217 rsp2: u64,
218 rsv1: u64,
219 ist1: u64,
220 ist2: u64,
221 ist3: u64,
222 ist4: u64,
223 ist5: u64,
224 ist6: u64,
225 ist7: u64,
226 rsv2: u64,
227 rsv3: u16,
228 iomap_base: u16,
229 }
230
231 struct GDTDesc {
232 limit: u16,
233 base: u64,
234 }
235
236 let mut gdt: [GDTEntry; 16];
237 let mut tss: TSSEntry;
238 let mut gdt_d: GDTDesc;
239
240 fn set_gdt_entry(n: u64, base: u32, limit: u32, access: u8, flags: u8) {
241 gdt[n].base_low = (base & 0xFFFF) as u16;
242 gdt[n].base_mid = ((base >> 16) & 0xFF) as u8;
243 gdt[n].base_hi = ((base >> 24) & 0xFF) as u8;
244 gdt[n].limit_low = (limit & 0xFFFF) as u16;
245 gdt[n].flags_limit = (((limit >> 16) & 0x0F) as u8) | (flags & 0xF0);
246 gdt[n].access = access;
247 }
248
249 fn set_gdt_tss(n: u64, base: u64, limit: u32) {
250 // 64-bit TSS Girdisi 16 bayttır (2 ardışık slot)
251 set_gdt_entry(n, (base & 0xFFFFFFFF) as u32, limit, 0x89, 0x00);
252 let high_entry = (&gdt[n + 1]) as ptr<u32>;
253 *(high_entry) = (base >> 32) as u32;
254 *(high_entry + 1) = 0; // Ayrılmış alan
255 }
256
257 fn init_gdt_64() {
258 gdt_d.limit = (sizeof(GDTEntry) * 16) - 1;
259 gdt_d.base = &gdt[0] as u64;
260
261 memset(&gdt[0] as ptr<u8>, 0, sizeof(GDTEntry) * 16);
262 memset(&tss as ptr<u8>, 0, sizeof(TSSEntry));
263 tss.iomap_base = sizeof(TSSEntry) as u16;
264
265 set_gdt_entry(0, 0, 0, 0, 0); // Null
266 set_gdt_entry(1, 0, 0xFFFFF, 0x9A, 0xA0); // 64-bit Kernel Code (0x08)
267 set_gdt_entry(2, 0, 0xFFFFF, 0x92, 0xC0); // Kernel Data (0x10)
268 set_gdt_entry(3, 0, 0xFFFFF, 0xFA, 0xA0); // User Code (0x18)
269 set_gdt_entry(4, 0, 0xFFFFF, 0xF2, 0xC0); // User Data (0x20)
270
271 set_gdt_tss(5, &tss as u64, (sizeof(TSSEntry) - 1) as u32); // TSS (0x28)
272
273 asm {
274 "lgdt [rdi]\n"
275 "push 0x08\n"
276 "lea rax, [rip + .next]\n"
277 "push rax\n"
278 "retfq\n"
279 ".next:\n"
280 "mov ax, 0x10\n"
281 "mov ds, ax\n"
282 "mov es, ax\n"
283 "mov fs, ax\n"
284 "mov gs, ax\n"
285 "mov ss, ax\n"
286 "mov ax, 0x28\n"
287 "ltr ax"
288 in rdi = &gdt_d;
289 }
290 }
291
292 // --- IDT Yapılandırması ---
293 struct IDTEntry {
294 offset_low: u16,
295 selector: u16,
296 ist: u8,
297 flags: u8,
298 offset_mid: u16,
299 offset_high: u32,
300 reserved: u32,
301 }
302
303 struct IDTDesc {
304 limit: u16,
305 base: u64,
306 }
307
308 let mut idt: [IDTEntry; 256];
309 let mut idt_d: IDTDesc;
310
311 fn set_idt_entry(n: u8, handler: u64, selector: u16, flags: u8, ist: u8) {
312 idt[n].offset_low = (handler & 0xFFFF) as u16;
313 idt[n].offset_mid = ((handler >> 16) & 0xFFFF) as u16;
314 idt[n].offset_high = (handler >> 32) as u32;
315 idt[n].selector = selector;
316 idt[n].ist = ist & 0x7;
317 idt[n].flags = flags;
318 idt[n].reserved = 0;
319 }
320
321 fn generic_exception_halt() {
322 asm { "cli\n.loop:\n hlt\n jmp .loop" }
323 }
324
325 fn init_idt_64() {
326 idt_d.limit = (sizeof(IDTEntry) * 256) - 1;
327 idt_d.base = &idt[0] as u64;
328
329 for i in 0..256 {
330 set_idt_entry(i as u8, generic_exception_halt as u64, 0x08, 0x8E, 0);
331 }
332
333 asm {
334 "lidt [rax]\n"
335 in rax = &idt_d;
336 }
337 }
338
339 // --- Fiziksel Bellek Yöneticisi (PMM) ---
340 const PAGE_SIZE: u64 = 4096;
341 const MAX_MEM_MB: u64 = 32768; // 32 GB
342 const PMM_BITMAP_SIZE: u64 = (MAX_MEM_MB * 1024 * 1024) / (PAGE_SIZE * 64);
343
344 let mut pmm_bitmap: [u64; PMM_BITMAP_SIZE as usize];
345 let mut pmm_lock: Spinlock;
346 let mut pmm_used_blocks: u64 = 0;
347 let mut pmm_max_blocks: u64 = 0;
348
349 fn pmm_bitmap_set(bit: u64) {
350 pmm_bitmap[(bit / 64) as usize] |= (1u64 << (bit % 64));
351 }
352
353 fn pmm_bitmap_unset(bit: u64) {
354 pmm_bitmap[(bit / 64) as usize] &= !(1u64 << (bit % 64));
355 }
356
357 fn pmm_bitmap_test(bit: u64) -> bool {
358 return (pmm_bitmap[(bit / 64) as usize] & (1u64 << (bit % 64))) != 0;
359 }
360
361 fn pmm_init(mem_size_kb: u64) {
362 spin_init(&pmm_lock);
363 pmm_max_blocks = (mem_size_kb * 1024) / PAGE_SIZE;
364 if pmm_max_blocks > (PMM_BITMAP_SIZE * 64) {
365 pmm_max_blocks = PMM_BITMAP_SIZE * 64;
366 }
367 pmm_used_blocks = pmm_max_blocks;
368 memset(&pmm_bitmap[0] as ptr<u8>, 0xFF, PMM_BITMAP_SIZE * 8);
369 }
370
371 fn pmm_init_region(base: u64, size: u64) {
372 spin_lock(&pmm_lock);
373 let align_base = base / PAGE_SIZE;
374 let blocks = size / PAGE_SIZE;
375 for i in 0..blocks {
376 let bit = align_base + i;
377 if bit < pmm_max_blocks && pmm_bitmap_test(bit) {
378 pmm_bitmap_unset(bit);
379 pmm_used_blocks = pmm_used_blocks - 1;
380 }
381 }
382 spin_unlock(&pmm_lock);
383 pmm_bitmap_set(0); // Sayfa 0 (NULL pointer alanı) koruması
384 }
385
386 fn pmm_alloc_block() -> u64 {
387 spin_lock(&pmm_lock);
388 if pmm_used_blocks >= pmm_max_blocks {
389 spin_unlock(&pmm_lock);
390 return 0;
391 }
392 let words = pmm_max_blocks / 64;
393 for i in 0..words {
394 if pmm_bitmap[i as usize] != 0xFFFFFFFFFFFFFFFF {
395 for j in 0..64 {
396 let bit = i * 64 + j;
397 if bit >= pmm_max_blocks { break; }
398 if !pmm_bitmap_test(bit) {
399 pmm_bitmap_set(bit);
400 pmm_used_blocks = pmm_used_blocks + 1;
401 spin_unlock(&pmm_lock);
402 return bit * PAGE_SIZE;
403 }
404 }
405 }
406 }
407 spin_unlock(&pmm_lock);
408 return 0;
409 }
410
411 fn pmm_free_block(addr: u64) {
412 spin_lock(&pmm_lock);
413 let bit = addr / PAGE_SIZE;
414 if bit < pmm_max_blocks && pmm_bitmap_test(bit) {
415 pmm_bitmap_unset(bit);
416 pmm_used_blocks = pmm_used_blocks - 1;
417 }
418 spin_unlock(&pmm_lock);
419 }
420
421 // --- Sanal Bellek Yöneticisi (VMM) ---
422 struct PageTableEntry {
423 entry: u64,
424 }
425
426 fn pte_set_frame(pte: ptr<PageTableEntry>, frame: u64, flags: u64) {
427 (*pte).entry = (frame & 0x000FFFFFFFFFF000) | (flags & 0xFFF);
428 }
429 fn pte_is_present(pte: ptr<PageTableEntry>) -> bool {
430 return ((*pte).entry & 1) != 0;
431 }
432 fn pte_get_frame(pte: ptr<PageTableEntry>) -> u64 {
433 return (*pte).entry & 0x000FFFFFFFFFF000;
434 }
435
436 struct PageTable {
437 entries: [PageTableEntry; 512],
438 }
439
440 let mut vmm_pml4: ptr<PageTable>;
441 let mut vmm_lock: Spinlock;
442
443 fn vmm_get_pt_indices(virt: u64) -> (u64, u64, u64, u64) {
444 return (
445 (virt >> 39) & 0x1FF,
446 (virt >> 30) & 0x1FF,
447 (virt >> 21) & 0x1FF,
448 (virt >> 12) & 0x1FF,
449 );
450 }
451
452 fn vmm_map_page(phys: u64, virt: u64, flags: u64) {
453 spin_lock(&vmm_lock);
454 let (pml4_i, pdpt_i, pd_i, pt_i) = vmm_get_pt_indices(virt);
455
456 let mut pml4e = &((*vmm_pml4).entries[pml4_i as usize]) as ptr<PageTableEntry>;
457 if !pte_is_present(pml4e) {
458 let new_pdpt = pmm_alloc_block();
459 memset(new_pdpt as ptr<u8>, 0, PAGE_SIZE);
460 pte_set_frame(pml4e, new_pdpt, 0x07); // Present, Writable, User
461 }
462
463 let pdpt = pte_get_frame(pml4e) as ptr<PageTable>;
464 let mut pdpte = &((*pdpt).entries[pdpt_i as usize]) as ptr<PageTableEntry>;
465 if !pte_is_present(pdpte) {
466 let new_pd = pmm_alloc_block();
467 memset(new_pd as ptr<u8>, 0, PAGE_SIZE);
468 pte_set_frame(pdpte, new_pd, 0x07);
469 }
470
471 let pd = pte_get_frame(pdpte) as ptr<PageTable>;
472 let mut pde = &((*pd).entries[pd_i as usize]) as ptr<PageTableEntry>;
473 if !pte_is_present(pde) {
474 let new_pt = pmm_alloc_block();
475 memset(new_pt as ptr<u8>, 0, PAGE_SIZE);
476 pte_set_frame(pde, new_pt, 0x07);
477 }
478
479 let pt = pte_get_frame(pde) as ptr<PageTable>;
480 let mut pte = &((*pt).entries[pt_i as usize]) as ptr<PageTableEntry>;
481 pte_set_frame(pte, phys, flags | 1);
482
483 invlpg(virt);
484 spin_unlock(&vmm_lock);
485 }
486
487 fn vmm_init() {
488 spin_init(&vmm_lock);
489 let pml4_phys = pmm_alloc_block();
490 vmm_pml4 = pml4_phys as ptr<PageTable>;
491 memset(vmm_pml4 as ptr<u8>, 0, PAGE_SIZE);
492
493 // Çekirdeğin ilk 4 GB'ını Identity Mapping ile doğrudan eşle
494 let mut phys: u64 = 0;
495 while phys < 0x100000000 {
496 vmm_map_page(phys, phys, 3); // Present + R/W
497 phys = phys + PAGE_SIZE;
498 }
499
500 asm { "mov cr3, rax" in rax = pml4_phys; }
501 }
502
503 // --- ACPI Doğrulama ve Ayrıştırma ---
504 struct RSDPDescriptor20 {
505 signature: [u8; 8],
506 checksum: u8,
507 oem_id: [u8; 6],
508 revision: u8,
509 rsdt_address: u32,
510 length: u32,
511 xsdt_address: u64,
512 extended_checksum: u8,
513 reserved: [u8; 3],
514 }
515
516 struct ACPISDTHeader {
517 signature: [u8; 4],
518 length: u32,
519 revision: u8,
520 checksum: u8,
521 oem_id: [u8; 6],
522 oem_table_id: [u8; 8],
523 oem_revision: u32,
524 creator_id: u32,
525 creator_revision: u32,
526 }
527
528 fn acpi_checksum(ptr: ptr<u8>, length: u32) -> bool {
529 let mut sum: u8 = 0;
530 for i in 0..length {
531 sum = sum + *(ptr + i as u64);
532 }
533 return sum == 0;
534 }
535
536 fn acpi_find_rsdp() -> ptr<RSDPDescriptor20> {
537 let mut current: u64 = 0x000E0000;
538 while current < 0x000FFFFF {
539 if memcmp(current as ptr<u8>, "RSD PTR " as ptr<u8>, 8) == 0 {
540 let rsdp = current as ptr<RSDPDescriptor20>;
541 // Revizyon 2.0+ ise genişletilmiş checksum ve boyutu doğrula
542 if (*rsdp).revision >= 2 {
543 if acpi_checksum(current as ptr<u8>, (*rsdp).length) {
544 return rsdp;
545 }
546 } else {
547 if acpi_checksum(current as ptr<u8>, 20) {
548 return rsdp;
549 }
550 }
551 }
552 current = current + 16;
553 }
554 return 0 as ptr<RSDPDescriptor20>;
555 }
556
557 const LAPIC_ID: u32 = 0x0020;
558 const LAPIC_VER: u32 = 0x0030;
559 const LAPIC_TPR: u32 = 0x0080;
560 const LAPIC_APR: u32 = 0x0090;
561 const LAPIC_PPR: u32 = 0x00A0;
562 const LAPIC_EOI: u32 = 0x00B0;
563 const LAPIC_RRD: u32 = 0x00C0;
564 const LAPIC_LDR: u32 = 0x00D0;
565 const LAPIC_DFR: u32 = 0x00E0;
566 const LAPIC_SVR: u32 = 0x00F0;
567 const LAPIC_ISR: u32 = 0x0100;
568 const LAPIC_TMR: u32 = 0x0180;
569 const LAPIC_IRR: u32 = 0x0200;
570 const LAPIC_ESR: u32 = 0x0280;
571 const LAPIC_ICRLO: u32 = 0x0300;
572 const LAPIC_ICRHI: u32 = 0x0310;
573 const LAPIC_TIMER: u32 = 0x0320;
574 const LAPIC_THERMAL: u32 = 0x0330;
575 const LAPIC_PERF: u32 = 0x0340;
576 const LAPIC_LINT0: u32 = 0x0350;
577 const LAPIC_LINT1: u32 = 0x0360;
578 const LAPIC_ERROR: u32 = 0x0370;
579 const LAPIC_TICR: u32 = 0x0380;
580 const LAPIC_TCCR: u32 = 0x0390;
581 const LAPIC_TDCR: u32 = 0x03E0;
582 fn lapic_write(reg: u32, val: u32) {
583 let ptr = (global_lapic_base + reg as u64) as ptr<u32>;
584 *ptr = val;
585 }
586 fn lapic_read(reg: u32) -> u32 {
587 let ptr = (global_lapic_base + reg as u64) as ptr<u32>;
588 return *ptr;
589 }
590 fn lapic_eoi() {
591 lapic_write(LAPIC_EOI, 0);
592 }
593 fn lapic_init_cpu() {
594 lapic_write(LAPIC_DFR, 0xFFFFFFFF);
595 lapic_write(LAPIC_LDR, (lapic_read(LAPIC_LDR) & 0x00FFFFFF) | 1);
596 lapic_write(LAPIC_LINT0, 0x10000);
597 lapic_write(LAPIC_LINT1, 0x10000);
598 lapic_write(LAPIC_TPR, 0);
599 lapic_write(LAPIC_SVR, 0x1FF);
600 }
601 fn ioapic_write(reg: u8, val: u32) {
602 let sel = global_ioapic_base as ptr<u32>;
603 let win = (global_ioapic_base + 0x10) as ptr<u32>;
604 *sel = reg as u32;
605 *win = val;
606 }
607 fn ioapic_read(reg: u8) -> u32 {
608 let sel = global_ioapic_base as ptr<u32>;
609 let win = (global_ioapic_base + 0x10) as ptr<u32>;
610 *sel = reg as u32;
611 return *win;
612 }
613 fn ioapic_set_entry(irq: u8, vector: u8, apic_id: u8) {
614 let low_idx = 0x10 + irq * 2;
615 let high_idx = 0x10 + irq * 2 + 1;
616 let low_val = vector as u32;
617 let high_val = (apic_id as u32) << 24;
618 ioapic_write(low_idx, low_val);
619 ioapic_write(high_idx, high_val);
620 }
621 struct MCFGAllocation {
622 base_address: u64,
623 pci_segment_group: u16,
624 start_bus_number: u8,
625 end_bus_number: u8,
626 reserved: u32,
627 }
628 struct PCIDeviceExt {
629 base: u64,
630 seg: u16,
631 bus: u8,
632 dev: u8,
633 func: u8,
634 vendor_id: u16,
635 device_id: u16,
636 class_code: u8,
637 subclass: u8,
638 prog_if: u8,
639 bar0: u64,
640 bar1: u64,
641 bar2: u64,
642 bar3: u64,
643 bar4: u64,
644 bar5: u64,
645 irq: u8,
646 }
647 let mut pcie_devices: [PCIDeviceExt; 2048];
648 let mut pcie_device_count: u64 = 0;
649 fn pcie_read_16(base: u64, bus: u8, dev: u8, func: u8, offset: u16) -> u16 {
650 let addr = base | ((bus as u64) << 20) | ((dev as u64) << 15) | ((func as u64) << 12) | (offset as u64);
651 return *(addr as ptr<u16>);
652 }
653 fn pcie_read_32(base: u64, bus: u8, dev: u8, func: u8, offset: u16) -> u32 {
654 let addr = base | ((bus as u64) << 20) | ((dev as u64) << 15) | ((func as u64) << 12) | (offset as u64);
655 return *(addr as ptr<u32>);
656 }
657 fn pcie_write_32(base: u64, bus: u8, dev: u8, func: u8, offset: u16, val: u32) {
658 let addr = base | ((bus as u64) << 20) | ((dev as u64) << 15) | ((func as u64) << 12) | (offset as u64);
659 *(addr as ptr<u32>) = val;
660 }
661 fn pcie_scan_bus(base: u64, seg: u16, bus: u8) {
662 for dev in 0..32 {
663 let vendor = pcie_read_16(base, bus, dev as u8, 0, 0x00);
664 if vendor != 0xFFFF {
665 pcie_scan_func(base, seg, bus, dev as u8, 0);
666 let header_type = (pcie_read_32(base, bus, dev as u8, 0, 0x0C) >> 16) & 0xFF;
667 if (header_type & 0x80) != 0 {
668 for func in 1..8 {
669 if pcie_read_16(base, bus, dev as u8, func as u8, 0x00) != 0xFFFF {
670 pcie_scan_func(base, seg, bus, dev as u8, func as u8);
671 }
672 }
673 }
674 }
675 }
676 }
677 fn pcie_scan_func(base: u64, seg: u16, bus: u8, dev: u8, func: u8) {
678 let vendor = pcie_read_16(base, bus, dev, func, 0x00);
679 let device = pcie_read_16(base, bus, dev, func, 0x02);
680 let class_info = pcie_read_32(base, bus, dev, func, 0x08);
681 let irq_info = pcie_read_32(base, bus, dev, func, 0x3C);
682
683 let mut ext: PCIDeviceExt;
684 ext.base = base;
685 ext.seg = seg;
686 ext.bus = bus;
687 ext.dev = dev;
688 ext.func = func;
689 ext.vendor_id = vendor;
690 ext.device_id = device;
691 ext.class_code = (class_info >> 24) as u8;
692 ext.subclass = (class_info >> 16) as u8;
693 ext.prog_if = (class_info >> 8) as u8;
694 ext.irq = (irq_info & 0xFF) as u8;
695
696 let b0 = pcie_read_32(base, bus, dev, func, 0x10);
697 if (b0 & 4) != 0 {
698 ext.bar0 = (b0 & 0xFFFFFFF0) as u64 | ((pcie_read_32(base, bus, dev, func, 0x14) as u64) << 32);
699 } else {
700 ext.bar0 = (b0 & 0xFFFFFFF0) as u64;
701 }
702
703 let b5 = pcie_read_32(base, bus, dev, func, 0x24);
704 if (b5 & 4) != 0 {
705 ext.bar5 = (b5 & 0xFFFFFFF0) as u64 | ((pcie_read_32(base, bus, dev, func, 0x28) as u64) << 32);
706 } else {
707 ext.bar5 = (b5 & 0xFFFFFFF0) as u64;
708 }
709 pcie_devices[pcie_device_count as usize] = ext;
710 pcie_device_count = pcie_device_count + 1;
711 }
712 fn pcie_init() {
713 if acpi_mcfg == 0 as ptr<MCFGHeader> { return; }
714 let entries = ((*acpi_mcfg).header.length - sizeof(MCFGHeader) as u32) / sizeof(MCFGAllocation) as u32;
715 let allocs = (acpi_mcfg as u64 + sizeof(MCFGHeader) as u64) as ptr<MCFGAllocation>;
716
717 for i in 0..entries {
718 let alloc = &(*allocs.offset(i as isize));
719 for bus in (*alloc).start_bus_number..=(*alloc).end_bus_number {
720 pcie_scan_bus((*alloc).base_address, (*alloc).pci_segment_group, bus);
721 }
722 }
723 }
724 struct AHCIPortRegs {
725 clb: u64,
726 fb: u64,
727 is: u32,
728 ie: u32,
729 cmd: u32,
730 rsv0: u32,
731 tfd: u32,
732 sig: u32,
733 ssts: u32,
734 sctl: u32,
735 serr: u32,
736 sact: u32,
737 ci: u32,
738 sntf: u32,
739 fbs: u32,
740 devslp: u32,
741 rsv1: [u32; 10],
742 vendor: [u32; 4],
743 }
744 struct AHCIHBARegs {
745 cap: u32,
746 ghc: u32,
747 is: u32,
748 pi: u32,
749 vs: u32,
750 ccc_ctl: u32,
751 ccc_pts: u32,
752 em_loc: u32,
753 em_ctl: u32,
754 cap2: u32,
755 bohc: u32,
756 rsv: [u8; 116],
757 ports: [AHCIPortRegs; 32],
758 }
759 struct AHCICmdHeader {
760 cfl_p_r_c: u16,
761 prdtl: u16,
762 prdbc: u32,
763 ctba: u64,
764 rsv1: [u32; 4],
765 }
766 struct AHCIPRDTEntry {
767 dba: u64,
768 rsv0: u32,
769 dbc_i: u32,
770 }
771 struct AHCICmdTable {
772 cfis: [u8; 64],
773 acmd: [u8; 16],
774 rsv: [u8; 48],
775 prdt_entry: [AHCIPRDTEntry; 65536 / 8],
776 }
777 let mut global_ahci_hba: ptr<AHCIHBARegs>;
778 fn ahci_port_start(port: ptr<AHCIPortRegs>) {
779 while ((*port).cmd & 0x8000) != 0 {}
780 (*port).cmd |= 0x0010;
781 (*port).cmd |= 0x0001;
782 }
783 fn ahci_port_stop(port: ptr<AHCIPortRegs>) {
784 (*port).cmd &= !0x0001;
785 (*port).cmd &= !0x0010;
786 while ((*port).cmd & 0x4000) != 0 || ((*port).cmd & 0x8000) != 0 {}
787 }
788 fn ahci_init_port(port: ptr<AHCIPortRegs>) {
789 ahci_port_stop(port);
790 let clb_phys = pmm_alloc_block();
791 let fb_phys = pmm_alloc_block();
792 let ctba_phys = pmm_alloc_block();
793
794 (*port).clb = clb_phys;
795 (*port).fb = fb_phys;
796
797 let cmd_header = clb_phys as ptr<AHCICmdHeader>;
798 memset(cmd_header as ptr<u8>, 0, 1024);
799 memset(fb_phys as ptr<u8>, 0, 256);
800 memset(ctba_phys as ptr<u8>, 0, PAGE_SIZE);
801
802 (*cmd_header).prdtl = 1;
803 (*cmd_header).ctba = ctba_phys;
804
805 ahci_port_start(port);
806 }
807 fn ahci_init_controller(bar5: u64) {
808 global_ahci_hba = bar5 as ptr<AHCIHBARegs>;
809 (*global_ahci_hba).ghc |= 0x80000000;
810
811 for i in 0..32 {
812 let pi = (*global_ahci_hba).pi;
813 if (pi & (1 << i)) != 0 {
814 let port = &((*global_ahci_hba).ports[i as usize]) as ptr<AHCIPortRegs>;
815 let ssts = (*port).ssts;
816 let ipm = (ssts >> 8) & 0x0F;
817 let det = ssts & 0x0F;
818 let sig = (*port).sig;
819
820 if det == 3 && ipm == 1 {
821 if sig == 0x00000101 {
822 ahci_init_port(port);
823 }
824 }
825 }
826 }
827 }
828 struct NVMeBarRegs {
829 cap: u64,
830 vs: u32,
831 intms: u32,
832 intmc: u32,
833 cc: u32,
834 csts: u32,
835 nssr: u32,
836 aqa: u32,
837 asq: u64,
838 acq: u64,
839 cmbloc: u32,
840 cmbsz: u32,
841 bpinfo: u32,
842 bprsel: u32,
843 bpmbl: u64,
844 cmbmsc: u64,
845 cmbsts: u32,
846 }
847 struct NVMeCmd {
848 cdw0: u32,
849 nsid: u32,
850 rsv2: u64,
851 mptr: u64,
852 dptr1: u64,
853 dptr2: u64,
854 cdw10: u32,
855 cdw11: u32,
856 cdw12: u32,
857 cdw13: u32,
858 cdw14: u32,
859 cdw15: u32,
860 }
861 struct NVMeCpl {
862 cdw0: u32,
863 rsv1: u32,
864 sqhd: u16,
865 sqid: u16,
866 cid: u16,
867 status: u16,
868 }
869 let mut global_nvme_bar: ptr<NVMeBarRegs>;
870 let mut nvme_admin_sq: ptr<NVMeCmd>;
871 let mut nvme_admin_cq: ptr<NVMeCpl>;
872 let mut nvme_sq_tail: u32 = 0;
873 let mut nvme_cq_head: u32 = 0;
874 let mut nvme_cq_phase: u16 = 1;
875 fn nvme_submit_cmd(cmd: ptr<NVMeCmd>) {
876 let mut sq_ptr = nvme_admin_sq as u64 + (nvme_sq_tail as u64 * sizeof(NVMeCmd) as u64);
877 memcpy(sq_ptr as ptr<u8>, cmd as ptr<u8>, sizeof(NVMeCmd) as u64);
878 nvme_sq_tail = (nvme_sq_tail + 1) % 64;
879 let doorbell = (global_nvme_bar as u64 + 0x1000) as ptr<u32>;
880 *doorbell = nvme_sq_tail;
881 }
882 fn nvme_poll_cq() -> ptr<NVMeCpl> {
883 let mut cq_ptr = (nvme_admin_cq as u64 + (nvme_cq_head as u64 * sizeof(NVMeCpl) as u64)) as ptr<NVMeCpl>;
884 while ((*cq_ptr).status & 0x01) != nvme_cq_phase {
885 cpu_pause();
886 }
887 nvme_cq_head = (nvme_cq_head + 1) % 64;
888 if nvme_cq_head == 0 {
889 nvme_cq_phase = nvme_cq_phase ^ 1;
890 }
891 let doorbell = (global_nvme_bar as u64 + 0x1004) as ptr<u32>;
892 *doorbell = nvme_cq_head;
893 return cq_ptr;
894 }
895 fn nvme_init_controller(bar0: u64) {
896 global_nvme_bar = bar0 as ptr<NVMeBarRegs>;
897 (*global_nvme_bar).cc &= 0xFFFFFFFE;
898 while ((*global_nvme_bar).csts & 1) != 0 { }
899 nvme_admin_sq = pmm_alloc_blocks(1) as ptr<NVMeCmd>;
900 nvme_admin_cq = pmm_alloc_blocks(1) as ptr<NVMeCpl>;
901 memset(nvme_admin_sq as ptr<u8>, 0, PAGE_SIZE);
902 memset(nvme_admin_cq as ptr<u8>, 0, PAGE_SIZE);
903 (*global_nvme_bar).aqa = 0x003F003F;
904 (*global_nvme_bar).asq = nvme_admin_sq as u64;
905 (*global_nvme_bar).acq = nvme_admin_cq as u64;
906 let iocqes = 4;
907 let iosqes = 6;
908 (*global_nvme_bar).cc = (iocqes << 20) | (iosqes << 16) | 0x00460001;
909 while ((*global_nvme_bar).csts & 1) == 0 { }
910 }
911 struct XHCICapRegs {
912 caplength: u8,
913 rsvd: u8,
914 hciversion: u16,
915 hcsparams1: u32,
916 hcsparams2: u32,
917 hcsparams3: u32,
918 hccparams1: u32,
919 dboff: u32,
920 rtsoff: u32,
921 hccparams2: u32,
922 }
923 struct XHCIOpRegs {
924 usbcmd: u32,
925 usbsts: u32,
926 pagesize: u32,
927 rsvd1: [u32; 2],
928 dnctrl: u32,
929 crcr: u64,
930 rsvd2: [u32; 4],
931 dcbaap: u64,
932 config: u32,
933 }
934 struct XHCIPortRegs {
935 portsc: u32,
936 portpmsc: u32,
937 portli: u32,
938 porthlpmc: u32,
939 }
940 struct XHCITrb {
941 param: u64,
942 status: u32,
943 control: u32,
944 }
945 let mut global_xhci_cap: ptr<XHCICapRegs>;
946 let mut global_xhci_op: ptr<XHCIOpRegs>;
947 let mut xhci_cmd_ring: ptr<XHCITrb>;
948 let mut xhci_dcbaa: ptr<u64>;
949 fn xhci_reset() {
950 (*global_xhci_op).usbcmd &= 0xFFFFFFFE;
951 while ((*global_xhci_op).usbsts & 1) == 0 { }
952 (*global_xhci_op).usbcmd |= 2;
953 while ((*global_xhci_op).usbcmd & 2) != 0 { }
954 while ((*global_xhci_op).usbsts & (1 << 11)) != 0 { }
955 }
956 fn xhci_init_controller(bar0: u64) {
957 global_xhci_cap = bar0 as ptr<XHCICapRegs>;
958 global_xhci_op = (bar0 + (*global_xhci_cap).caplength as u64) as ptr<XHCIOpRegs>;
959 xhci_reset();
960 let max_slots = (*global_xhci_cap).hcsparams1 & 0xFF;
961 (*global_xhci_op).config = max_slots;
962 xhci_dcbaa = pmm_alloc_blocks(1) as ptr<u64>;
963 memset(xhci_dcbaa as ptr<u8>, 0, PAGE_SIZE);
964 (*global_xhci_op).dcbaap = xhci_dcbaa as u64;
965 xhci_cmd_ring = pmm_alloc_blocks(1) as ptr<XHCITrb>;
966 memset(xhci_cmd_ring as ptr<u8>, 0, PAGE_SIZE);
967 (*global_xhci_op).crcr = (xhci_cmd_ring as u64) | 1;
968 (*global_xhci_op).usbcmd |= 1;
969 while ((*global_xhci_op).usbsts & 1) != 0 { }
970 }
971 let mut rtl_iobase: u64 = 0;
972 let mut rtl_rx_buffer: ptr<u8>;
973 let mut rtl_tx_buffers: [ptr<u8>; 4];
974 let mut rtl_tx_idx: u8 = 0;
975 fn rtl_outb(offset: u16, data: u8) { outb((rtl_iobase + offset as u64) as u16, data); }
976 fn rtl_outw(offset: u16, data: u16) { outw((rtl_iobase + offset as u64) as u16, data); }
977 fn rtl_outl(offset: u16, data: u32) { outl((rtl_iobase + offset as u64) as u16, data); }
978 fn rtl_inb(offset: u16) -> u8 { return inb((rtl_iobase + offset as u64) as u16); }
979 fn rtl_inw(offset: u16) -> u16 { return inw((rtl_iobase + offset as u64) as u16); }
980 fn rtl_inl(offset: u16) -> u32 { return inl((rtl_iobase + offset as u64) as u16); }
981 fn rtl8139_init(bar0: u64) {
982 rtl_iobase = bar0 & 0xFFFFFFFFFFFFFFFC;
983 rtl_outb(0x52, 0);
984 rtl_outb(0x37, 0x10);
985 while (rtl_inb(0x37) & 0x10) != 0 { }
986 rtl_rx_buffer = pmm_alloc_blocks(3) as ptr<u8>;
987 memset(rtl_rx_buffer, 0, 8192 + 16 + 1500);
988 rtl_outl(0x30, rtl_rx_buffer as u64 as u32);
989 for i in 0..4 {
990 rtl_tx_buffers[i] = pmm_alloc_blocks(1) as ptr<u8>;
991 memset(rtl_tx_buffers[i], 0, PAGE_SIZE);
992 }
993 rtl_outw(0x3C, 0x0005);
994 let rx_config: u32 = 0x0000000F | 0x00000080;
995 rtl_outl(0x44, rx_config);
996 rtl_outb(0x37, 0x0C);
997 }
998 fn rtl8139_send(packet: ptr<u8>, length: u32) {
999 let tx_addr = rtl_tx_buffers[rtl_tx_idx as usize];
1000 memcpy(tx_addr, packet, length as u64);
1001 let port = 0x20 + (rtl_tx_idx as u16 * 4);
1002 rtl_outl(port, tx_addr as u64 as u32);
1003 let status_port = 0x10 + (rtl_tx_idx as u16 * 4);
1004 rtl_outl(status_port, length);
1005 rtl_tx_idx = (rtl_tx_idx + 1) % 4;
1006 }
1007 struct MacAddr { addr: [u8; 6] }
1008 struct Ipv4Addr { addr: [u8; 4] }
1009 struct EthernetHeader {
1010 dest_mac: MacAddr,
1011 src_mac: MacAddr,
1012 ethertype: u16,
1013 }
1014 struct ArpHeader {
1015 hw_type: u16,
1016 proto_type: u16,
1017 hw_len: u8,
1018 proto_len: u8,
1019 opcode: u16,
1020 sender_mac: MacAddr,
1021 sender_ip: Ipv4Addr,
1022 target_mac: MacAddr,
1023 target_ip: Ipv4Addr,
1024 }
1025 struct Ipv4Header {
1026 ihl_version: u8,
1027 tos: u8,
1028 total_length: u16,
1029 id: u16,
1030 flags_frag: u16,
1031 ttl: u8,
1032 protocol: u8,
1033 checksum: u16,
1034 src_ip: Ipv4Addr,
1035 dest_ip: Ipv4Addr,
1036 }
1037 struct UdpHeader {
1038 src_port: u16,
1039 dest_port: u16,
1040 length: u16,
1041 checksum: u16,
1042 }
1043 struct TcpHeader {
1044 src_port: u16,
1045 dest_port: u16,
1046 seq_num: u32,
1047 ack_num: u32,
1048 data_offset_flags: u16,
1049 window_size: u16,
1050 checksum: u16,
1051 urgent_ptr: u16,
1052 }
1053 let mut system_mac: MacAddr;
1054 let mut system_ip: Ipv4Addr;
1055 fn htons(hostshort: u16) -> u16 {
1056 return (hostshort >> 8) | (hostshort << 8);
1057 }
1058 fn htonl(hostlong: u32) -> u32 {
1059 return ((hostlong & 0xFF) << 24) | ((hostlong & 0xFF00) << 8) | ((hostlong & 0xFF0000) >> 8) | ((hostlong >> 24) & 0xFF);
1060 }
1061 fn calculate_checksum(data: ptr<u8>, length: u32) -> u16 {
1062 let mut sum: u32 = 0;
1063 let mut ptr16 = data as ptr<u16>;
1064 let mut len = length;
1065 while len > 1 {
1066 sum = sum + *ptr16 as u32;
1067 ptr16 = (ptr16 as u64 + 2) as ptr<u16>;
1068 len = len - 2;
1069 }
1070 if len == 1 {
1071 let mut last_byte: u16 = 0;
1072 *(last_byte as u64 as ptr<u8>) = *(ptr16 as ptr<u8>);
1073 sum = sum + last_byte as u32;
1074 }
1075 while (sum >> 16) != 0 {
1076 sum = (sum & 0xFFFF) + (sum >> 16);
1077 }
1078 return (!sum) as u16;
1079 }
1080 fn arp_send_request(target_ip: Ipv4Addr) {
1081 let packet_size = sizeof(EthernetHeader) as u64 + sizeof(ArpHeader) as u64;
1082 let packet = pmm_alloc_blocks(1) as ptr<u8>;
1083 let eth = packet as ptr<EthernetHeader>;
1084 for i in 0..6 { (*eth).dest_mac.addr[i] = 0xFF; }
1085 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
1086 (*eth).ethertype = htons(0x0806);
1087
1088 let arp = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<ArpHeader>;
1089 (*arp).hw_type = htons(0x0001);
1090 (*arp).proto_type = htons(0x0800);
1091 (*arp).hw_len = 6;
1092 (*arp).proto_len = 4;
1093 (*arp).opcode = htons(0x0001);
1094 for i in 0..6 { (*arp).sender_mac.addr[i] = system_mac.addr[i]; }
1095 for i in 0..4 { (*arp).sender_ip.addr[i] = system_ip.addr[i]; }
1096 for i in 0..6 { (*arp).target_mac.addr[i] = 0x00; }
1097 for i in 0..4 { (*arp).target_ip.addr[i] = target_ip.addr[i]; }
1098
1099 rtl8139_send(packet, packet_size as u32);
1100 pmm_free_block(packet as u64);
1101 }
1102 struct CpuContext {
1103 r15: u64, r14: u64, r13: u64, r12: u64,
1104 r11: u64, r10: u64, r9: u64, r8: u64,
1105 rdi: u64, rsi: u64, rbp: u64, rbx: u64,
1106 rdx: u64, rcx: u64, rax: u64,
1107 rip: u64, cs: u64, rflags: u64, rsp: u64, ss: u64,
1108 }
1109 struct ProcessControlBlock {
1110 pid: u64,
1111 cr3_phys: u64,
1112 context: ptr<CpuContext>,
1113 state: u8,
1114 priority: u8,
1115 time_slice: u64,
1116 next: ptr<ProcessControlBlock>,
1117 }
1118 let mut current_process: ptr<ProcessControlBlock>;
1119 let mut process_queue: ptr<ProcessControlBlock>;
1120 let mut global_pid_counter: u64 = 1000;
1121 fn create_process(entry_point: u64, is_kernel: bool) -> ptr<ProcessControlBlock> {
1122 let pcb = pmm_alloc_blocks(1) as ptr<ProcessControlBlock>;
1123 memset(pcb as ptr<u8>, 0, sizeof(ProcessControlBlock) as u64);
1124 (*pcb).pid = global_pid_counter;
1125 global_pid_counter = global_pid_counter + 1;
1126 let stack_phys = pmm_alloc_blocks(4);
1127 let stack_top = stack_phys + (PAGE_SIZE * 4);
1128 let ctx = (stack_top - sizeof(CpuContext) as u64) as ptr<CpuContext>;
1129 memset(ctx as ptr<u8>, 0, sizeof(CpuContext) as u64);
1130 (*ctx).rip = entry_point;
1131 (*ctx).rflags = 0x202;
1132 (*ctx).rsp = stack_top;
1133 if is_kernel {
1134 (*ctx).cs = 0x08;
1135 (*ctx).ss = 0x10;
1136 (*pcb).cr3_phys = vmm_pml4 as u64;
1137 } else {
1138 (*ctx).cs = 0x1B;
1139 (*ctx).ss = 0x23;
1140 (*pcb).cr3_phys = pmm_alloc_blocks(1);
1141 memset((*pcb).cr3_phys as ptr<u8>, 0, PAGE_SIZE);
1142 }
1143 (*pcb).context = ctx;
1144 (*pcb).state = 1;
1145 (*pcb).time_slice = 10;
1146 (*pcb).next = process_queue;
1147 process_queue = pcb;
1148 return pcb;
1149 }
1150 fn switch_context(next: ptr<ProcessControlBlock>) {
1151 let prev = current_process;
1152 current_process = next;
1153 asm {
1154 "mov rsp, %0\n"
1155 "mov cr3, %1\n"
1156 "pop r15\n pop r14\n pop r13\n pop r12\n"
1157 "pop r11\n pop r10\n pop r9\n pop r8\n"
1158 "pop rdi\n pop rsi\n pop rbp\n pop rbx\n"
1159 "pop rdx\n pop rcx\n pop rax\n"
1160 "iretq"
1161 in "%0" = (*next).context;
1162 in "%1" = (*next).cr3_phys;
1163 }
1164 }
1165 fn scheduler_tick() {
1166 if current_process == 0 as ptr<ProcessControlBlock> {
1167 if process_queue != 0 as ptr<ProcessControlBlock> {
1168 switch_context(process_queue);
1169 }
1170 return;
1171 }
1172 (*current_process).time_slice = (*current_process).time_slice - 1;
1173 if (*current_process).time_slice == 0 {
1174 (*current_process).time_slice = 10;
1175 let mut next = (*current_process).next;
1176 if next == 0 as ptr<ProcessControlBlock> {
1177 next = process_queue;
1178 }
1179 if next != current_process {
1180 switch_context(next);
1181 }
1182 }
1183 }
1184 struct VfsStat {
1185 size: u64,
1186 inode: u64,
1187 flags: u32,
1188 uid: u32,
1189 gid: u32,
1190 }
1191 struct VfsNode {
1192 name: [u8; 128],
1193 mask: u32,
1194 uid: u32,
1195 gid: u32,
1196 flags: u32,
1197 inode: u64,
1198 length: u64,
1199 read_fn: u64,
1200 write_fn: u64,
1201 open_fn: u64,
1202 close_fn: u64,
1203 readdir_fn: u64,
1204 finddir_fn: u64,
1205 ptr: u64,
1206 parent: ptr<VfsNode>,
1207 children: ptr<VfsNode>,
1208 next: ptr<VfsNode>,
1209 }
1210 struct FileDescriptor {
1211 node: ptr<VfsNode>,
1212 offset: u64,
1213 flags: u32,
1214 }
1215 let mut global_vfs_root: ptr<VfsNode>;
1216 let mut next_inode: u64 = 1;
1217 fn vfs_init_system() {
1218 global_vfs_root = pmm_alloc_blocks(1) as ptr<VfsNode>;
1219 memset(global_vfs_root as ptr<u8>, 0, sizeof(VfsNode) as u64);
1220 strcpy(&((*global_vfs_root).name[0]), "/" as ptr<u8>);
1221 (*global_vfs_root).flags = 0x07;
1222 (*global_vfs_root).inode = 0;
1223 }
1224 fn vfs_create_node(parent: ptr<VfsNode>, name: ptr<u8>, flags: u32) -> ptr<VfsNode> {
1225 let node = pmm_alloc_blocks(1) as ptr<VfsNode>;
1226 memset(node as ptr<u8>, 0, sizeof(VfsNode) as u64);
1227 strcpy(&((*node).name[0]), name);
1228 (*node).flags = flags;
1229 (*node).inode = next_inode;
1230 next_inode = next_inode + 1;
1231 (*node).parent = parent;
1232 if (*parent).children == 0 as ptr<VfsNode> {
1233 (*parent).children = node;
1234 } else {
1235 let mut curr = (*parent).children;
1236 while (*curr).next != 0 as ptr<VfsNode> {
1237 curr = (*curr).next;
1238 }
1239 (*curr).next = node;
1240 }
1241 return node;
1242 }
1243 fn vfs_find_child(parent: ptr<VfsNode>, name: ptr<u8>) -> ptr<VfsNode> {
1244 let mut curr = (*parent).children;
1245 while curr != 0 as ptr<VfsNode> {
1246 if strcmp(&((*curr).name[0]), name) == 0 {
1247 return curr;
1248 }
1249 curr = (*curr).next;
1250 }
1251 return 0 as ptr<VfsNode>;
1252 }
1253 fn vfs_read(fd: ptr<FileDescriptor>, buffer: ptr<u8>, size: u64) -> u64 {
1254 if (*fd).node == 0 as ptr<VfsNode> { return 0; }
1255 if ((*(*fd).node).flags & 0x07) != 0 { return 0; }
1256 let mut read_sz = size;
1257 if (*fd).offset + size > (*(*fd).node).length {
1258 read_sz = (*(*fd).node).length - (*fd).offset;
1259 }
1260 let data_ptr = (*(*fd).node).ptr as ptr<u8>;
1261 memcpy(buffer, (data_ptr as u64 + (*fd).offset) as ptr<u8>, read_sz);
1262 (*fd).offset = (*fd).offset + read_sz;
1263 return read_sz;
1264 }
1265 fn vfs_write(fd: ptr<FileDescriptor>, buffer: ptr<u8>, size: u64) -> u64 {
1266 if (*fd).node == 0 as ptr<VfsNode> { return 0; }
1267 if ((*(*fd).node).flags & 0x07) != 0 { return 0; }
1268 let data_ptr = (*(*fd).node).ptr as ptr<u8>;
1269 memcpy((data_ptr as u64 + (*fd).offset) as ptr<u8>, buffer, size);
1270 (*fd).offset = (*fd).offset + size;
1271 if (*fd).offset > (*(*fd).node).length {
1272 (*(*fd).node).length = (*fd).offset;
1273 }
1274 return size;
1275 }
1276 let mut sha256_k: [u32; 64] = [
1277 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1278 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1279 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1280 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1281 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1282 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1283 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1284 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1285 ];
1286 fn rotr32(x: u32, n: u32) -> u32 { return (x >> n) | (x << (32 - n)); }
1287 fn ch(x: u32, y: u32, z: u32) -> u32 { return (x & y) ^ (!x & z); }
1288 fn maj(x: u32, y: u32, z: u32) -> u32 { return (x & y) ^ (x & z) ^ (y & z); }
1289 fn sig0(x: u32) -> u32 { return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); }
1290 fn sig1(x: u32) -> u32 { return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); }
1291 fn ep0(x: u32) -> u32 { return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3); }
1292 fn ep1(x: u32) -> u32 { return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10); }
1293 struct Sha256Ctx {
1294 state: [u32; 8],
1295 count: [u32; 2],
1296 buffer: [u8; 64],
1297 }
1298 fn sha256_transform(ctx: ptr<Sha256Ctx>, data: ptr<u8>) {
1299 let mut w: [u32; 64];
1300 for i in 0..16 {
1301 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);
1302 }
1303 for i in 16..64 {
1304 w[i] = ep1(w[i - 2]) + w[i - 7] + ep0(w[i - 15]) + w[i - 16];
1305 }
1306 let mut a = (*ctx).state[0]; let mut b = (*ctx).state[1]; let mut c = (*ctx).state[2]; let mut d = (*ctx).state[3];
1307 let mut e = (*ctx).state[4]; let mut f = (*ctx).state[5]; let mut g = (*ctx).state[6]; let mut h = (*ctx).state[7];
1308 for i in 0..64 {
1309 let t1 = h + sig1(e) + ch(e, f, g) + sha256_k[i] + w[i];
1310 let t2 = sig0(a) + maj(a, b, c);
1311 h = g; g = f; f = e; e = d + t1;
1312 d = c; c = b; b = a; a = t1 + t2;
1313 }
1314 (*ctx).state[0] += a; (*ctx).state[1] += b; (*ctx).state[2] += c; (*ctx).state[3] += d;
1315 (*ctx).state[4] += e; (*ctx).state[5] += f; (*ctx).state[6] += g; (*ctx).state[7] += h;
1316 }
1317 fn sha256_init(ctx: ptr<Sha256Ctx>) {
1318 (*ctx).count[0] = 0; (*ctx).count[1] = 0;
1319 (*ctx).state[0] = 0x6a09e667; (*ctx).state[1] = 0xbb67ae85;
1320 (*ctx).state[2] = 0x3c6ef372; (*ctx).state[3] = 0xa54ff53a;
1321 (*ctx).state[4] = 0x510e527f; (*ctx).state[5] = 0x9b05688c;
1322 (*ctx).state[6] = 0x1f83d9ab; (*ctx).state[7] = 0x5be0cd19;
1323 }
1324 let mut aes_sbox: [u8; 256] = [
1325 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
1326 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
1327 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
1328 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
1329 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
1330 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
1331 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
1332 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
1333 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
1334 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
1335 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
1336 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
1337 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
1338 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
1339 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
1340 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
1341 ];
1342 fn sub_word(w: u32) -> u32 {
1343 let b0 = aes_sbox[(w & 0xFF) as usize] as u32;
1344 let b1 = aes_sbox[((w >> 8) & 0xFF) as usize] as u32;
1345 let b2 = aes_sbox[((w >> 16) & 0xFF) as usize] as u32;
1346 let b3 = aes_sbox[((w >> 24) & 0xFF) as usize] as u32;
1347 return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
1348 }
1349 struct CompositorWindow {
1350 id: u64,
1351 x: u32,
1352 y: u32,
1353 width: u32,
1354 height: u32,
1355 z_index: u32,
1356 flags: u32,
1357 title: [u8; 64],
1358 buffer_phys: u64,
1359 next: ptr<CompositorWindow>,
1360 }
1361 let mut comp_root_window: ptr<CompositorWindow>;
1362 let mut comp_active_window: ptr<CompositorWindow>;
1363 let mut comp_back_buffer: ptr<u32>;
1364 let mut comp_width: u32 = 1920;
1365 let mut comp_height: u32 = 1080;
1366 let mut comp_next_id: u64 = 1;
1367 fn comp_init(fb_base: u64, w: u32, h: u32) {
1368 comp_width = w;
1369 comp_height = h;
1370 comp_back_buffer = pmm_alloc_blocks((w * h * 4) / PAGE_SIZE + 1) as ptr<u32>;
1371 memset(comp_back_buffer as ptr<u8>, 0, (w * h * 4) as u64);
1372 fb_ptr = fb_base as ptr<u32>;
1373 }
1374 fn comp_create_window(x: u32, y: u32, w: u32, h: u32, title: ptr<u8>) -> ptr<CompositorWindow> {
1375 let win = pmm_alloc_blocks(1) as ptr<CompositorWindow>;
1376 memset(win as ptr<u8>, 0, sizeof(CompositorWindow) as u64);
1377 (*win).id = comp_next_id;
1378 comp_next_id = comp_next_id + 1;
1379 (*win).x = x;
1380 (*win).y = y;
1381 (*win).width = w;
1382 (*win).height = h;
1383 (*win).z_index = 100;
1384 strcpy(&((*win).title[0]), title);
1385 let buf_sz = w * h * 4;
1386 (*win).buffer_phys = pmm_alloc_blocks(buf_sz as u64 / PAGE_SIZE + 1);
1387 memset((*win).buffer_phys as ptr<u8>, 0xFF, buf_sz as u64);
1388 (*win).next = comp_root_window;
1389 comp_root_window = win;
1390 comp_active_window = win;
1391 return win;
1392 }
1393 fn comp_draw_rect(win: ptr<CompositorWindow>, x: u32, y: u32, w: u32, h: u32, color: u32) {
1394 let buf = (*win).buffer_phys as ptr<u32>;
1395 for i in 0..h {
1396 for j in 0..w {
1397 if (x + j) < (*win).width && (y + i) < (*win).height {
1398 *(buf + ((y + i) * (*win).width + (x + j)) as u64) = color;
1399 }
1400 }
1401 }
1402 }
1403 fn comp_render() {
1404 let bg_color = 0x2c3e50;
1405 for i in 0..(comp_width * comp_height) {
1406 *(comp_back_buffer + i as u64) = bg_color;
1407 }
1408 let mut curr = comp_root_window;
1409 while curr != 0 as ptr<CompositorWindow> {
1410 let buf = (*curr).buffer_phys as ptr<u32>;
1411 for i in 0..(*curr).height {
1412 for j in 0..(*curr).width {
1413 let screen_y = (*curr).y + i;
1414 let screen_x = (*curr).x + j;
1415 if screen_x < comp_width && screen_y < comp_height {
1416 let pixel = *(buf + (i * (*curr).width + j) as u64);
1417 *(comp_back_buffer + (screen_y * comp_width + screen_x) as u64) = pixel;
1418 }
1419 }
1420 }
1421 curr = (*curr).next;
1422 }
1423 memcpy(fb_ptr as ptr<u8>, comp_back_buffer as ptr<u8>, (comp_width * comp_height * 4) as u64);
1424 }
1425 const ELF_MAGIC: u32 = 0x464C457F;
1426 struct Elf64_Ehdr {
1427 e_ident: [u8; 16],
1428 e_type: u16,
1429 e_machine: u16,
1430 e_version: u32,
1431 e_entry: u64,
1432 e_phoff: u64,
1433 e_shoff: u64,
1434 e_flags: u32,
1435 e_ehsize: u16,
1436 e_phentsize: u16,
1437 e_phnum: u16,
1438 e_shentsize: u16,
1439 e_shnum: u16,
1440 e_shstrndx: u16,
1441 }
1442 struct Elf64_Phdr {
1443 p_type: u32,
1444 p_flags: u32,
1445 p_offset: u64,
1446 p_vaddr: u64,
1447 p_paddr: u64,
1448 p_filesz: u64,
1449 p_memsz: u64,
1450 p_align: u64,
1451 }
1452 struct AegisPermissionMatrix {
1453 uid: u32,
1454 gid: u32,
1455 capabilities: u64,
1456 network_access: u8,
1457 fs_access: u8,
1458 hw_access: u8,
1459 max_memory: u64,
1460 }
1461 let mut global_aegis_matrix: [AegisPermissionMatrix; 1024];
1462 let mut aegis_matrix_count: u32 = 0;
1463 fn aegis_register_process(pid: u64, uid: u32, gid: u32, caps: u64) {
1464 let mut idx = aegis_matrix_count;
1465 global_aegis_matrix[idx as usize].uid = uid;
1466 global_aegis_matrix[idx as usize].gid = gid;
1467 global_aegis_matrix[idx as usize].capabilities = caps;
1468 global_aegis_matrix[idx as usize].network_access = 1;
1469 global_aegis_matrix[idx as usize].fs_access = 1;
1470 global_aegis_matrix[idx as usize].hw_access = 0;
1471 global_aegis_matrix[idx as usize].max_memory = 0x10000000;
1472 aegis_matrix_count = aegis_matrix_count + 1;
1473 }
1474 fn aegis_verify_execution(node: ptr<VfsNode>, uid: u32) -> bool {
1475 if (*node).uid != uid && uid != 0 {
1476 if ((*node).flags & 0x01) == 0 {
1477 return false;
1478 }
1479 }
1480 return true;
1481 }
1482 fn elf_check_header(hdr: ptr<Elf64_Ehdr>) -> bool {
1483 let magic = *(hdr as ptr<u32>);
1484 if magic != ELF_MAGIC { return false; }
1485 if (*hdr).e_ident[4] != 2 { return false; }
1486 if (*hdr).e_ident[5] != 1 { return false; }
1487 if (*hdr).e_machine != 62 { return false; }
1488 return true;
1489 }
1490 fn elf_load_segment(phdr: ptr<Elf64_Phdr>, fd: ptr<FileDescriptor>, cr3: u64) {
1491 let mut vaddr = (*phdr).p_vaddr;
1492 let memsz = (*phdr).p_memsz;
1493 let filesz = (*phdr).p_filesz;
1494 let offset = (*phdr).p_offset;
1495
1496 let pages = (memsz + PAGE_SIZE - 1) / PAGE_SIZE;
1497 let mut current_vaddr = vaddr & !(PAGE_SIZE - 1);
1498
1499 for i in 0..pages {
1500 let phys = pmm_alloc_blocks(1);
1501 memset(phys as ptr<u8>, 0, PAGE_SIZE);
1502 let flags = 0x07;
1503 vmm_map_page(phys, current_vaddr, flags);
1504 current_vaddr = current_vaddr + PAGE_SIZE;
1505 }
1506
1507 (*fd).offset = offset;
1508 let mut buffer = vaddr as ptr<u8>;
1509 vfs_read(fd, buffer, filesz);
1510 }
1511 fn execve_ring3(path: ptr<u8>, uid: u32, gid: u32) -> u64 {
1512 let root = global_vfs_root;
1513 let mut curr = root;
1514 let mut node = vfs_find_child(curr, path);
1515 if node == 0 as ptr<VfsNode> { return 0; }
1516
1517 if !aegis_verify_execution(node, uid) { return 0; }
1518
1519 let mut fd: FileDescriptor;
1520 fd.node = node;
1521 fd.offset = 0;
1522 fd.flags = 0;
1523
1524 let mut hdr_buf: [u8; 64];
1525 vfs_read(&fd, &hdr_buf[0] as ptr<u8>, 64);
1526 let ehdr = &hdr_buf[0] as ptr<Elf64_Ehdr>;
1527
1528 if !elf_check_header(ehdr) { return 0; }
1529
1530 let process = create_process((*ehdr).e_entry, false);
1531 aegis_register_process((*process).pid, uid, gid, 0xFFFFFFFF);
1532
1533 let phdr_size = (*ehdr).e_phnum as u64 * (*ehdr).e_phentsize as u64;
1534 let phdr_buf = pmm_alloc_blocks((phdr_size / PAGE_SIZE) + 1) as ptr<u8>;
1535
1536 fd.offset = (*ehdr).e_phoff;
1537 vfs_read(&fd, phdr_buf, phdr_size);
1538
1539 for i in 0..(*ehdr).e_phnum {
1540 let phdr = (phdr_buf as u64 + (i as u64 * (*ehdr).e_phentsize as u64)) as ptr<Elf64_Phdr>;
1541 if (*phdr).p_type == 1 {
1542 elf_load_segment(phdr, &fd, (*process).cr3_phys);
1543 }
1544 }
1545
1546 pmm_free_blocks(phdr_buf as u64, (phdr_size / PAGE_SIZE) + 1);
1547 return (*process).pid;
1548 }
1549 struct IpcMessage {
1550 sender_pid: u64,
1551 target_pid: u64,
1552 msg_type: u32,
1553 length: u32,
1554 data: [u8; 112],
1555 next: ptr<IpcMessage>,
1556 }
1557 struct IpcQueue {
1558 owner_pid: u64,
1559 head: ptr<IpcMessage>,
1560 tail: ptr<IpcMessage>,
1561 msg_count: u32,
1562 lock: Spinlock,
1563 }
1564 let mut global_ipc_queues: [IpcQueue; 1024];
1565 let mut ipc_queue_count: u32 = 0;
1566 fn ipc_create_queue(pid: u64) {
1567 let mut q = &global_ipc_queues[ipc_queue_count as usize];
1568 (*q).owner_pid = pid;
1569 (*q).head = 0 as ptr<IpcMessage>;
1570 (*q).tail = 0 as ptr<IpcMessage>;
1571 (*q).msg_count = 0;
1572 spin_init(&((*q).lock));
1573 ipc_queue_count = ipc_queue_count + 1;
1574 }
1575 fn ipc_send_message(target_pid: u64, sender_pid: u64, mtype: u32, data: ptr<u8>, len: u32) -> u32 {
1576 let mut target_q = 0 as ptr<IpcQueue>;
1577 for i in 0..ipc_queue_count {
1578 if global_ipc_queues[i as usize].owner_pid == target_pid {
1579 target_q = &global_ipc_queues[i as usize];
1580 }
1581 }
1582 if target_q == 0 as ptr<IpcQueue> { return 1; }
1583
1584 let msg = pmm_alloc_blocks(1) as ptr<IpcMessage>;
1585 memset(msg as ptr<u8>, 0, sizeof(IpcMessage) as u64);
1586 (*msg).sender_pid = sender_pid;
1587 (*msg).target_pid = target_pid;
1588 (*msg).msg_type = mtype;
1589 let mut c_len = len;
1590 if c_len > 112 { c_len = 112; }
1591 (*msg).length = c_len;
1592 memcpy(&((*msg).data[0]) as ptr<u8>, data, c_len as u64);
1593 (*msg).next = 0 as ptr<IpcMessage>;
1594
1595 spin_lock(&((*target_q).lock));
1596 if (*target_q).tail == 0 as ptr<IpcMessage> {
1597 (*target_q).head = msg;
1598 (*target_q).tail = msg;
1599 } else {
1600 (*((*target_q).tail)).next = msg;
1601 (*target_q).tail = msg;
1602 }
1603 (*target_q).msg_count = (*target_q).msg_count + 1;
1604 spin_unlock(&((*target_q).lock));
1605 return 0;
1606 }
1607 fn ipc_receive_message(pid: u64, out_msg: ptr<IpcMessage>) -> u32 {
1608 let mut my_q = 0 as ptr<IpcQueue>;
1609 for i in 0..ipc_queue_count {
1610 if global_ipc_queues[i as usize].owner_pid == pid {
1611 my_q = &global_ipc_queues[i as usize];
1612 }
1613 }
1614 if my_q == 0 as ptr<IpcQueue> { return 1; }
1615
1616 spin_lock(&((*my_q).lock));
1617 if (*my_q).head == 0 as ptr<IpcMessage> {
1618 spin_unlock(&((*my_q).lock));
1619 return 2;
1620 }
1621
1622 let msg = (*my_q).head;
1623 (*my_q).head = (*msg).next;
1624 if (*my_q).head == 0 as ptr<IpcMessage> {
1625 (*my_q).tail = 0 as ptr<IpcMessage>;
1626 }
1627 (*my_q).msg_count = (*my_q).msg_count - 1;
1628 spin_unlock(&((*my_q).lock));
1629
1630 memcpy(out_msg as ptr<u8>, msg as ptr<u8>, sizeof(IpcMessage) as u64);
1631 pmm_free_blocks(msg as u64, 1);
1632 return 0;
1633 }
1634 fn sys_read_wrap(fd_ptr: u64, buf: u64, size: u64) -> u64 {
1635 let fd = fd_ptr as ptr<FileDescriptor>;
1636 return vfs_read(fd, buf as ptr<u8>, size);
1637 }
1638 fn sys_write_wrap(fd_ptr: u64, buf: u64, size: u64) -> u64 {
1639 let fd = fd_ptr as ptr<FileDescriptor>;
1640 return vfs_write(fd, buf as ptr<u8>, size);
1641 }
1642 fn sys_mmap(addr: u64, len: u64, prot: u64, flags: u64, fd_ptr: u64, offset: u64) -> u64 {
1643 let pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
1644 let mut vaddr = addr;
1645 if vaddr == 0 {
1646 vaddr = 0x4000000000;
1647 }
1648 let mut cur = vaddr;
1649 for i in 0..pages {
1650 let phys = pmm_alloc_blocks(1);
1651 memset(phys as ptr<u8>, 0, PAGE_SIZE);
1652 vmm_map_page(phys, cur, prot);
1653 cur = cur + PAGE_SIZE;
1654 }
1655 if fd_ptr != 0 {
1656 let fd = fd_ptr as ptr<FileDescriptor>;
1657 let old_off = (*fd).offset;
1658 (*fd).offset = offset;
1659 vfs_read(fd, vaddr as ptr<u8>, len);
1660 (*fd).offset = old_off;
1661 }
1662 return vaddr;
1663 }
1664 fn syscall_handler_64_adv() {
1665 let mut rax: u64; let mut rdi: u64; let mut rsi: u64;
1666 let mut rdx: u64; let mut r10: u64; let mut r8: u64; let mut r9: u64;
1667
1668 asm { "mov %0, rax" out rax = rax; }
1669 asm { "mov %0, rdi" out rdi = rdi; }
1670 asm { "mov %0, rsi" out rsi = rsi; }
1671 asm { "mov %0, rdx" out rdx = rdx; }
1672 asm { "mov %0, r10" out r10 = r10; }
1673 asm { "mov %0, r8" out r8 = r8; }
1674 asm { "mov %0, r9" out r9 = r9; }
1675 if rax == 0 {
1676 asm { "mov rax, %0" in rax = sys_read_wrap(rdi, rsi, rdx); }
1677 } else if rax == 1 {
1678 asm { "mov rax, %0" in rax = sys_write_wrap(rdi, rsi, rdx); }
1679 } else if rax == 2 {
1680 let node = vfs_find_child(global_vfs_root, rdi as ptr<u8>);
1681 if node == 0 as ptr<VfsNode> {
1682 asm { "mov rax, 0" }
1683 } else {
1684 let fd = pmm_alloc_blocks(1) as ptr<FileDescriptor>;
1685 (*fd).node = node; (*fd).offset = 0; (*fd).flags = rsi as u32;
1686 asm { "mov rax, %0" in rax = fd as u64; }
1687 }
1688 } else if rax == 3 {
1689 pmm_free_blocks(rdi, 1);
1690 asm { "mov rax, 0" }
1691 } else if rax == 9 {
1692 asm { "mov rax, %0" in rax = sys_mmap(rdi, rsi, rdx, r10, r8, r9); }
1693 } else if rax == 59 {
1694 asm { "mov rax, %0" in rax = execve_ring3(rdi as ptr<u8>, rsi as u32, rdx as u32); }
1695 } else if rax == 60 {
1696 (*current_process).state = 0;
1697 scheduler_tick();
1698 } else if rax == 100 {
1699 comp_draw_rect(rdi as ptr<CompositorWindow>, rsi as u32, rdx as u32, r10 as u32, r8 as u32, r9 as u32);
1700 asm { "mov rax, 0" }
1701 } else if rax == 200 {
1702 let ctx = rdi as ptr<Sha256Ctx>;
1703 sha256_init(ctx);
1704 sha256_transform(ctx, rsi as ptr<u8>);
1705 asm { "mov rax, 0" }
1706 } else if rax == 300 {
1707 asm { "mov rax, %0" in rax = ipc_send_message(rdi, rsi, rdx as u32, r10 as ptr<u8>, r8 as u32) as u64; }
1708 } else if rax == 301 {
1709 asm { "mov rax, %0" in rax = ipc_receive_message(rdi, rsi as ptr<IpcMessage>) as u64; }
1710 } else {
1711 asm { "mov rax, -1" }
1712 }
1713 }
1714 struct CpuCoreInfo {
1715 apic_id: u8,
1716 acpi_id: u8,
1717 is_bsp: bool,
1718 is_active: bool,
1719 stack_base: u64,
1720 current_task: u64,
1721 }
1722 let mut smp_cores: [CpuCoreInfo; 256];
1723 let mut smp_core_count: u32 = 0;
1724 let mut smp_bsp_id: u8 = 0;
1725 let mut smp_lock: Spinlock;
1726 fn smp_register_core(apic_id: u8, acpi_id: u8, is_bsp: bool) {
1727 let idx = smp_core_count;
1728 smp_cores[idx as usize].apic_id = apic_id;
1729 smp_cores[idx as usize].acpi_id = acpi_id;
1730 smp_cores[idx as usize].is_bsp = is_bsp;
1731 smp_cores[idx as usize].is_active = is_bsp;
1732 smp_cores[idx as usize].stack_base = pmm_alloc_blocks(4) + (PAGE_SIZE * 4);
1733 smp_cores[idx as usize].current_task = 0;
1734 smp_core_count = smp_core_count + 1;
1735 if is_bsp { smp_bsp_id = apic_id; }
1736 }
1737 fn smp_send_ipi(target_apic_id: u8, vector: u8, delivery_mode: u32, level: u32, trigger: u32) {
1738 let icr_low = (vector as u32) | (delivery_mode << 8) | (level << 14) | (trigger << 15);
1739 let icr_high = (target_apic_id as u32) << 24;
1740 lapic_write(LAPIC_ICRHI, icr_high);
1741 lapic_write(LAPIC_ICRLO, icr_low);
1742 while (lapic_read(LAPIC_ICRLO) & (1 << 12)) != 0 { cpu_pause(); }
1743 }
1744 fn smp_send_init(target_apic_id: u8) {
1745 smp_send_ipi(target_apic_id, 0, 5, 1, 1);
1746 for i in 0..10000 { cpu_pause(); }
1747 smp_send_ipi(target_apic_id, 0, 5, 0, 1);
1748 }
1749 fn smp_send_sipi(target_apic_id: u8, trampoline_page: u32) {
1750 let vector = (trampoline_page >> 12) as u8;
1751 smp_send_ipi(target_apic_id, vector, 6, 1, 0);
1752 }
1753 fn smp_boot_ap(core_idx: u32) {
1754 let target_apic = smp_cores[core_idx as usize].apic_id;
1755 if target_apic == smp_bsp_id { return; }
1756 let trampoline = 0x8000;
1757 smp_send_init(target_apic);
1758 for i in 0..100000 { cpu_pause(); }
1759 smp_send_sipi(target_apic, trampoline);
1760 for i in 0..50000 { cpu_pause(); }
1761 smp_send_sipi(target_apic, trampoline);
1762 }
1763 fn smp_init_all() {
1764 spin_init(&smp_lock);
1765 for i in 0..smp_core_count {
1766 smp_boot_ap(i);
1767 }
1768 }
1769 struct HdaGcapRegs {
1770 gcap: u16,
1771 vmin: u8,
1772 vmaj: u8,
1773 outpay: u16,
1774 inpay: u16,
1775 gctl: u32,
1776 wakeen: u16,
1777 statests: u16,
1778 gsts: u16,
1779 outstrm: u16,
1780 instrm: u16,
1781 bidir: u16,
1782 }
1783 struct HdaCorbRegs {
1784 corblbase: u32,
1785 corbubase: u32,
1786 corbwp: u16,
1787 corbrp: u16,
1788 corbctl: u8,
1789 corbsts: u8,
1790 corbsize: u8,
1791 rsvd: u8,
1792 }
1793 struct HdaRirbRegs {
1794 rirblbase: u32,
1795 rirbubase: u32,
1796 rirbwp: u16,
1797 rintcnt: u16,
1798 rirbctl: u8,
1799 rirbsts: u8,
1800 rirbsize: u8,
1801 rsvd: u8,
1802 }
1803 struct HdaStreamRegs {
1804 ctl0: u8,
1805 ctl1: u8,
1806 ctl2: u8,
1807 sts: u8,
1808 lpib: u32,
1809 cbl: u32,
1810 lvi: u16,
1811 fifos: u16,
1812 fmt: u16,
1813 rsvd: u16,
1814 bdpl: u32,
1815 bdpu: u32,
1816 }
1817 let mut global_hda_base: u64 = 0;
1818 let mut hda_corb_buf: ptr<u32>;
1819 let mut hda_rirb_buf: ptr<u64>;
1820 let mut hda_corb_wp: u16 = 0;
1821 let mut hda_rirb_rp: u16 = 0;
1822 let mut hda_codec_mask: u16 = 0;
1823 fn hda_reset_controller() {
1824 let gctl_ptr = (global_hda_base + 0x08) as ptr<u32>;
1825 *gctl_ptr = 0;
1826 while (*gctl_ptr & 1) != 0 { cpu_pause(); }
1827 *gctl_ptr = 1;
1828 while (*gctl_ptr & 1) == 0 { cpu_pause(); }
1829 for i in 0..50000 { cpu_pause(); }
1830 }
1831 fn hda_init_corb_rirb() {
1832 let corb_regs = (global_hda_base + 0x40) as ptr<HdaCorbRegs>;
1833 let rirb_regs = (global_hda_base + 0x50) as ptr<HdaRirbRegs>;
1834 (*corb_regs).corbctl = 0;
1835 (*rirb_regs).rirbctl = 0;
1836
1837 hda_corb_buf = pmm_alloc_blocks(1) as ptr<u32>;
1838 hda_rirb_buf = pmm_alloc_blocks(1) as ptr<u64>;
1839 memset(hda_corb_buf as ptr<u8>, 0, PAGE_SIZE);
1840 memset(hda_rirb_buf as ptr<u8>, 0, PAGE_SIZE);
1841
1842 (*corb_regs).corblbase = hda_corb_buf as u64 as u32;
1843 (*corb_regs).corbubase = (hda_corb_buf as u64 >> 32) as u32;
1844 (*rirb_regs).rirblbase = hda_rirb_buf as u64 as u32;
1845 (*rirb_regs).rirbubase = (hda_rirb_buf as u64 >> 32) as u32;
1846
1847 (*corb_regs).corbrp = 0x8000;
1848 (*rirb_regs).rirbwp = 0x8000;
1849 (*corb_regs).corbwp = 0;
1850 hda_corb_wp = 0;
1851 hda_rirb_rp = 0;
1852
1853 (*corb_regs).corbctl = 2;
1854 (*rirb_regs).rirbctl = 2;
1855 }
1856 fn hda_send_verb(codec: u8, node: u8, payload: u32) {
1857 let verb = ((codec as u32) << 28) | ((node as u32) << 20) | payload;
1858 let corb_regs = (global_hda_base + 0x40) as ptr<HdaCorbRegs>;
1859 hda_corb_wp = hda_corb_wp + 1;
1860 if hda_corb_wp == 256 { hda_corb_wp = 0; }
1861 *(hda_corb_buf + hda_corb_wp as u64) = verb;
1862 (*corb_regs).corbwp = hda_corb_wp;
1863 }
1864 fn hda_read_response() -> u64 {
1865 let rirb_regs = (global_hda_base + 0x50) as ptr<HdaRirbRegs>;
1866 while (*rirb_regs).rirbwp == hda_rirb_rp { cpu_pause(); }
1867 hda_rirb_rp = hda_rirb_rp + 1;
1868 if hda_rirb_rp == 256 { hda_rirb_rp = 0; }
1869 return *(hda_rirb_buf + hda_rirb_rp as u64);
1870 }
1871 fn hda_init(bar0: u64) {
1872 global_hda_base = bar0;
1873 hda_reset_controller();
1874 let statests_ptr = (global_hda_base + 0x0E) as ptr<u16>;
1875 hda_codec_mask = *statests_ptr;
1876 hda_init_corb_rirb();
1877 }
1878 struct DhcpPacket {
1879 op: u8,
1880 htype: u8,
1881 hlen: u8,
1882 hops: u8,
1883 xid: u32,
1884 secs: u16,
1885 flags: u16,
1886 ciaddr: u32,
1887 yiaddr: u32,
1888 siaddr: u32,
1889 giaddr: u32,
1890 chaddr: [u8; 16],
1891 sname: [u8; 64],
1892 file: [u8; 128],
1893 magic: u32,
1894 options: [u8; 256],
1895 }
1896 struct DnsHeader {
1897 id: u16,
1898 flags: u16,
1899 qdcount: u16,
1900 ancount: u16,
1901 nscount: u16,
1902 arcount: u16,
1903 }
1904 let mut system_dns_ip: Ipv4Addr;
1905 let mut system_gateway_ip: Ipv4Addr;
1906 let mut system_subnet_mask: Ipv4Addr;
1907 let mut dhcp_xid: u32 = 0x1337AABB;
1908 fn dhcp_send_discover() {
1909 let pkt_size = sizeof(DhcpPacket) as u64;
1910 let pkt = pmm_alloc_blocks(1) as ptr<DhcpPacket>;
1911 memset(pkt as ptr<u8>, 0, pkt_size);
1912 (*pkt).op = 1;
1913 (*pkt).htype = 1;
1914 (*pkt).hlen = 6;
1915 (*pkt).hops = 0;
1916 (*pkt).xid = htonl(dhcp_xid);
1917 (*pkt).secs = 0;
1918 (*pkt).flags = htons(0x8000);
1919 (*pkt).ciaddr = 0;
1920 (*pkt).yiaddr = 0;
1921 (*pkt).siaddr = 0;
1922 (*pkt).giaddr = 0;
1923 for i in 0..6 { (*pkt).chaddr[i] = system_mac.addr[i]; }
1924 (*pkt).magic = htonl(0x63825363);
1925 (*pkt).options[0] = 53;
1926 (*pkt).options[1] = 1;
1927 (*pkt).options[2] = 1;
1928 (*pkt).options[3] = 255;
1929
1930 let mut broadcast_ip: Ipv4Addr;
1931 for i in 0..4 { broadcast_ip.addr[i] = 255; }
1932
1933 let udp_len = sizeof(UdpHeader) as u64 + pkt_size;
1934 let ip_len = sizeof(Ipv4Header) as u64 + udp_len;
1935 let eth_len = sizeof(EthernetHeader) as u64 + ip_len;
1936 let buffer = pmm_alloc_blocks(1) as ptr<u8>;
1937 memset(buffer, 0, eth_len);
1938
1939 let eth = buffer as ptr<EthernetHeader>;
1940 for i in 0..6 { (*eth).dest_mac.addr[i] = 0xFF; }
1941 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
1942 (*eth).ethertype = htons(0x0800);
1943
1944 let iph = (buffer as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
1945 (*iph).ihl_version = 0x45;
1946 (*iph).tos = 0;
1947 (*iph).total_length = htons(ip_len as u16);
1948 (*iph).id = htons(1);
1949 (*iph).flags_frag = 0;
1950 (*iph).ttl = 64;
1951 (*iph).protocol = 17;
1952 (*iph).src_ip.addr[0] = 0; (*iph).src_ip.addr[1] = 0; (*iph).src_ip.addr[2] = 0; (*iph).src_ip.addr[3] = 0;
1953 for i in 0..4 { (*iph).dest_ip.addr[i] = 255; }
1954 (*iph).checksum = calculate_checksum(iph as ptr<u8>, sizeof(Ipv4Header) as u32);
1955
1956 let udph = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<UdpHeader>;
1957 (*udph).src_port = htons(68);
1958 (*udph).dest_port = htons(67);
1959 (*udph).length = htons(udp_len as u16);
1960 (*udph).checksum = 0;
1961
1962 let payload = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64 + sizeof(UdpHeader) as u64) as ptr<u8>;
1963 memcpy(payload, pkt as ptr<u8>, pkt_size);
1964
1965 rtl8139_send(buffer, eth_len as u32);
1966 pmm_free_blocks(pkt as u64, 1);
1967 pmm_free_blocks(buffer as u64, 1);
1968 }
1969 fn dns_format_name(dest: ptr<u8>, domain: ptr<u8>) {
1970 let mut i: u64 = 0;
1971 let mut j: u64 = 0;
1972 let mut len_pos: u64 = 0;
1973 let mut count: u8 = 0;
1974 dest[len_pos] = 0;
1975 i = i + 1;
1976 while domain[j] != 0 {
1977 if domain[j] == 46 {
1978 dest[len_pos] = count;
1979 len_pos = i;
1980 count = 0;
1981 } else {
1982 dest[i] = domain[j];
1983 count = count + 1;
1984 }
1985 i = i + 1;
1986 j = j + 1;
1987 }
1988 dest[len_pos] = count;
1989 dest[i] = 0;
1990 }
1991 fn dns_send_query(domain: ptr<u8>) {
1992 let mut query_buf: [u8; 256];
1993 memset(&query_buf[0] as ptr<u8>, 0, 256);
1994 let dh = &query_buf[0] as ptr<DnsHeader>;
1995 (*dh).id = htons(0xABCD);
1996 (*dh).flags = htons(0x0100);
1997 (*dh).qdcount = htons(1);
1998 (*dh).ancount = 0;
1999 (*dh).nscount = 0;
2000 (*dh).arcount = 0;
2001
2002 let qname = (&query_buf[0] as u64 + sizeof(DnsHeader) as u64) as ptr<u8>;
2003 dns_format_name(qname, domain);
2004 let qname_len = strlen(qname) + 1;
2005
2006 let qtype = (qname as u64 + qname_len) as ptr<u16>;
2007 *qtype = htons(1);
2008 let qclass = (qname as u64 + qname_len + 2) as ptr<u16>;
2009 *qclass = htons(1);
2010
2011 let total_len = sizeof(DnsHeader) as u64 + qname_len + 4;
2012
2013 let eth_len = sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64 + sizeof(UdpHeader) as u64 + total_len;
2014 let buffer = pmm_alloc_blocks(1) as ptr<u8>;
2015 memset(buffer, 0, eth_len);
2016
2017 let eth = buffer as ptr<EthernetHeader>;
2018 for i in 0..6 { (*eth).dest_mac.addr[i] = 0xFF; }
2019 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
2020 (*eth).ethertype = htons(0x0800);
2021
2022 let iph = (buffer as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
2023 (*iph).ihl_version = 0x45;
2024 (*iph).tos = 0;
2025 (*iph).total_length = htons((sizeof(Ipv4Header) as u64 + sizeof(UdpHeader) as u64 + total_len) as u16);
2026 (*iph).id = htons(2);
2027 (*iph).flags_frag = 0;
2028 (*iph).ttl = 64;
2029 (*iph).protocol = 17;
2030 for i in 0..4 { (*iph).src_ip.addr[i] = system_ip.addr[i]; }
2031 for i in 0..4 { (*iph).dest_ip.addr[i] = system_dns_ip.addr[i]; }
2032 (*iph).checksum = calculate_checksum(iph as ptr<u8>, sizeof(Ipv4Header) as u32);
2033
2034 let udph = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<UdpHeader>;
2035 (*udph).src_port = htons(50000);
2036 (*udph).dest_port = htons(53);
2037 (*udph).length = htons((sizeof(UdpHeader) as u64 + total_len) as u16);
2038 (*udph).checksum = 0;
2039
2040 let payload = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64 + sizeof(UdpHeader) as u64) as ptr<u8>;
2041 memcpy(payload, &query_buf[0] as ptr<u8>, total_len);
2042
2043 rtl8139_send(buffer, eth_len as u32);
2044 pmm_free_blocks(buffer as u64, 1);
2045 }
2046 struct UsbCbw {
2047 signature: u32,
2048 tag: u32,
2049 transfer_length: u32,
2050 flags: u8,
2051 lun: u8,
2052 cb_length: u8,
2053 cdb: [u8; 16],
2054 }
2055 struct UsbCsw {
2056 signature: u32,
2057 tag: u32,
2058 data_residue: u32,
2059 status: u8,
2060 }
2061 fn usb_bot_read_capacity(bulk_out: u8, bulk_in: u8) {
2062 let cbw = pmm_alloc_blocks(1) as ptr<UsbCbw>;
2063 memset(cbw as ptr<u8>, 0, sizeof(UsbCbw) as u64);
2064 (*cbw).signature = 0x43425355;
2065 (*cbw).tag = 0x11223344;
2066 (*cbw).transfer_length = 8;
2067 (*cbw).flags = 0x80;
2068 (*cbw).lun = 0;
2069 (*cbw).cb_length = 10;
2070 (*cbw).cdb[0] = 0x25;
2071 pmm_free_blocks(cbw as u64, 1);
2072 }
2073 struct Psf1Header {
2074 magic: u16,
2075 mode: u8,
2076 charsize: u8,
2077 }
2078 struct Psf2Header {
2079 magic: u32,
2080 version: u32,
2081 headersize: u32,
2082 flags: u32,
2083 length: u32,
2084 charsize: u32,
2085 height: u32,
2086 width: u32,
2087 }
2088 let mut system_font_ptr: ptr<u8>;
2089 let mut system_font_w: u32 = 8;
2090 let mut system_font_h: u32 = 16;
2091 fn gui_draw_char(win: ptr<CompositorWindow>, c: u8, x: u32, y: u32, fg: u32, bg: u32) {
2092 let glyph_offset = c as u64 * system_font_h as u64;
2093 let glyph = (system_font_ptr as u64 + glyph_offset) as ptr<u8>;
2094 let buf = (*win).buffer_phys as ptr<u32>;
2095 for cy in 0..system_font_h {
2096 let row = *(glyph + cy as u64);
2097 for cx in 0..system_font_w {
2098 let px = x + cx;
2099 let py = y + cy;
2100 if px < (*win).width && py < (*win).height {
2101 let p_idx = (py * (*win).width + px) as u64;
2102 if (row & (0x80 >> cx)) != 0 {
2103 *(buf + p_idx) = fg;
2104 } else {
2105 if bg != 0xFFFFFFFF { *(buf + p_idx) = bg; }
2106 }
2107 }
2108 }
2109 }
2110 }
2111 fn gui_draw_string(win: ptr<CompositorWindow>, str: ptr<u8>, x: u32, y: u32, fg: u32, bg: u32) {
2112 let mut i: u64 = 0;
2113 let mut cx = x;
2114 while *(str + i) != 0 {
2115 if *(str + i) == 10 {
2116 cx = x;
2117 y = y + system_font_h + 2;
2118 } else {
2119 gui_draw_char(win, *(str + i), cx, y, fg, bg);
2120 cx = cx + system_font_w;
2121 }
2122 i = i + 1;
2123 }
2124 }
2125 fn gui_draw_button(win: ptr<CompositorWindow>, label: ptr<u8>, x: u32, y: u32, w: u32, h: u32) {
2126 comp_draw_rect(win, x, y, w, h, 0x555555);
2127 comp_draw_rect(win, x+1, y+1, w-2, h-2, 0x888888);
2128 let len = strlen(label) as u32;
2129 let text_x = x + (w / 2) - ((len * system_font_w) / 2);
2130 let text_y = y + (h / 2) - (system_font_h / 2);
2131 gui_draw_string(win, label, text_x, text_y, 0xFFFFFF, 0xFFFFFFFF);
2132 }
2133 fn gui_draw_panel(win: ptr<CompositorWindow>, title: ptr<u8>) {
2134 comp_draw_rect(win, 0, 0, (*win).width, (*win).height, 0x333333);
2135 comp_draw_rect(win, 0, 0, (*win).width, 24, 0x111111);
2136 gui_draw_string(win, title, 5, 4, 0xFFFFFF, 0x111111);
2137 gui_draw_button(win, "X" as ptr<u8>, (*win).width - 24, 2, 20, 20);
2138 }
2139 const TCP_STATE_CLOSED: u8 = 0;
2140 const TCP_STATE_LISTEN: u8 = 1;
2141 const TCP_STATE_SYN_SENT: u8 = 2;
2142 const TCP_STATE_SYN_RCVD: u8 = 3;
2143 const TCP_STATE_ESTABLISHED: u8 = 4;
2144 const TCP_STATE_FIN_WAIT_1: u8 = 5;
2145 const TCP_STATE_FIN_WAIT_2: u8 = 6;
2146 const TCP_STATE_CLOSE_WAIT: u8 = 7;
2147 const TCP_STATE_CLOSING: u8 = 8;
2148 const TCP_STATE_LAST_ACK: u8 = 9;
2149 const TCP_STATE_TIME_WAIT: u8 = 10;
2150 struct TcpSocket {
2151 id: u64,
2152 state: u8,
2153 local_port: u16,
2154 remote_port: u16,
2155 remote_ip: Ipv4Addr,
2156 seq_num: u32,
2157 ack_num: u32,
2158 window_size: u16,
2159 rx_buffer: ptr<u8>,
2160 tx_buffer: ptr<u8>,
2161 rx_head: u32,
2162 rx_tail: u32,
2163 tx_head: u32,
2164 tx_tail: u32,
2165 lock: Spinlock,
2166 is_active: bool,
2167 }
2168 let mut global_tcp_sockets: [TcpSocket; 1024];
2169 let mut tcp_socket_count: u64 = 1;
2170 fn tcp_init_sockets() {
2171 for i in 0..1024 {
2172 global_tcp_sockets[i].is_active = false;
2173 global_tcp_sockets[i].id = 0;
2174 spin_init(&(global_tcp_sockets[i].lock));
2175 }
2176 }
2177 fn tcp_create_socket() -> ptr<TcpSocket> {
2178 for i in 0..1024 {
2179 if !global_tcp_sockets[i].is_active {
2180 global_tcp_sockets[i].is_active = true;
2181 global_tcp_sockets[i].id = tcp_socket_count;
2182 tcp_socket_count = tcp_socket_count + 1;
2183 global_tcp_sockets[i].state = TCP_STATE_CLOSED;
2184 global_tcp_sockets[i].local_port = 0;
2185 global_tcp_sockets[i].remote_port = 0;
2186 global_tcp_sockets[i].seq_num = 0;
2187 global_tcp_sockets[i].ack_num = 0;
2188 global_tcp_sockets[i].window_size = 8192;
2189 global_tcp_sockets[i].rx_buffer = pmm_alloc_blocks(2) as ptr<u8>;
2190 global_tcp_sockets[i].tx_buffer = pmm_alloc_blocks(2) as ptr<u8>;
2191 global_tcp_sockets[i].rx_head = 0;
2192 global_tcp_sockets[i].rx_tail = 0;
2193 global_tcp_sockets[i].tx_head = 0;
2194 global_tcp_sockets[i].tx_tail = 0;
2195 return &global_tcp_sockets[i];
2196 }
2197 }
2198 return 0 as ptr<TcpSocket>;
2199 }
2200 fn tcp_compute_checksum(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, tcp_len: u16, tcp_data: ptr<u8>) -> u16 {
2201 let mut sum: u32 = 0;
2202 let src_ptr = &src_ip as ptr<Ipv4Addr> as ptr<u16>;
2203 let dst_ptr = &dst_ip as ptr<Ipv4Addr> as ptr<u16>;
2204 sum = sum + *(src_ptr) as u32;
2205 sum = sum + *(src_ptr as u64 + 2) as u32;
2206 sum = sum + *(dst_ptr) as u32;
2207 sum = sum + *(dst_ptr as u64 + 2) as u32;
2208 sum = sum + htons(6) as u32;
2209 sum = sum + htons(tcp_len) as u32;
2210
2211 let mut data_ptr = tcp_data as ptr<u16>;
2212 let mut len = tcp_len;
2213 while len > 1 {
2214 sum = sum + *(data_ptr) as u32;
2215 data_ptr = (data_ptr as u64 + 2) as ptr<u16>;
2216 len = len - 2;
2217 }
2218 if len == 1 {
2219 let mut last_byte: u16 = 0;
2220 *(last_byte as u64 as ptr<u8>) = *(data_ptr as ptr<u8>);
2221 sum = sum + last_byte as u32;
2222 }
2223 while (sum >> 16) != 0 {
2224 sum = (sum & 0xFFFF) + (sum >> 16);
2225 }
2226 return (!sum) as u16;
2227 }
2228
2229 fn tcp_send_segment(sock: ptr<TcpSocket>, flags: u16, payload: ptr<u8>, payload_len: u16) {
2230 let tcp_len = sizeof(TcpHeader) as u16 + payload_len;
2231 let ip_len = sizeof(Ipv4Header) as u16 + tcp_len;
2232 let eth_len = sizeof(EthernetHeader) as u16 + ip_len;
2233
2234 let buffer = pmm_alloc_blocks(1) as ptr<u8>;
2235 memset(buffer, 0, eth_len as u64);
2236
2237 let eth = buffer as ptr<EthernetHeader>;
2238 let dest_mac = arp_resolve_mac((*sock).remote_ip);
2239 for i in 0..6 { (*eth).dest_mac.addr[i] = dest_mac.addr[i]; }
2240 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
2241 (*eth).ethertype = htons(0x0800);
2242
2243 let iph = (buffer as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
2244 (*iph).ihl_version = 0x45;
2245 (*iph).tos = 0;
2246 (*iph).total_length = htons(ip_len);
2247 (*iph).id = htons((rand_next() & 0xFFFF) as u16);
2248 (*iph).flags_frag = htons(0x4000);
2249 (*iph).ttl = 64;
2250 (*iph).protocol = 6;
2251 for i in 0..4 { (*iph).src_ip.addr[i] = system_ip.addr[i]; }
2252 for i in 0..4 { (*iph).dest_ip.addr[i] = (*sock).remote_ip.addr[i]; }
2253 (*iph).checksum = 0;
2254 (*iph).checksum = calculate_checksum(iph as ptr<u8>, sizeof(Ipv4Header) as u32);
2255
2256 let tcph = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
2257 (*tcph).src_port = htons((*sock).local_port);
2258 (*tcph).dest_port = htons((*sock).remote_port);
2259 (*tcph).seq_num = htonl((*sock).seq_num);
2260 (*tcph).ack_num = htonl((*sock).ack_num);
2261 (*tcph).data_offset_flags = htons((5 << 12) | (flags & 0x01FF));
2262 (*tcph).window_size = htons((*sock).window_size);
2263 (*tcph).urgent_ptr = 0;
2264 (*tcph).checksum = 0;
2265
2266 let tcp_payload = (tcph as u64 + sizeof(TcpHeader) as u64) as ptr<u8>;
2267 if payload_len > 0 && payload != (0 as ptr<u8>) {
2268 memcpy(tcp_payload, payload, payload_len as u64);
2269 }
2270
2271 (*tcph).checksum = tcp_compute_checksum(system_ip, (*sock).remote_ip, tcp_len, tcph as ptr<u8>);
2272 rtl8139_send(buffer, eth_len as u32);
2273 pmm_free_blocks(buffer as u64, 1);
2274 }
2275
2276 fn tcp_connect(sock: ptr<TcpSocket>, remote_ip: Ipv4Addr, remote_port: u16) {
2277 spin_lock(&((*sock).lock));
2278 (*sock).remote_ip = remote_ip;
2279 (*sock).remote_port = remote_port;
2280 if (*sock).local_port == 0 {
2281 (*sock).local_port = 49152 + ((rand_next() % 16383) as u16);
2282 }
2283 (*sock).seq_num = (rand_next() & 0xFFFFFFFF) as u32;
2284 (*sock).ack_num = 0;
2285 (*sock).window_size = 8192;
2286 (*sock).state = TCP_STATE_SYN_SENT;
2287 tcp_send_segment(sock, 0x0002, 0 as ptr<u8>, 0);
2288 (*sock).seq_num += 1;
2289 spin_unlock(&((*sock).lock));
2290 }
2291
2292 fn tcp_close(sock: ptr<TcpSocket>) {
2293 spin_lock(&((*sock).lock));
2294 if (*sock).state == TCP_STATE_ESTABLISHED || (*sock).state == TCP_STATE_SYN_RCVD {
2295 (*sock).state = TCP_STATE_FIN_WAIT_1;
2296 tcp_send_segment(sock, 0x0011, 0 as ptr<u8>, 0);
2297 (*sock).seq_num += 1;
2298 } else {
2299 (*sock).state = TCP_STATE_CLOSED;
2300 (*sock).is_active = false;
2301 if (*sock).rx_buffer != (0 as ptr<u8>) {
2302 pmm_free_blocks((*sock).rx_buffer as u64, 2);
2303 (*sock).rx_buffer = 0 as ptr<u8>;
2304 }
2305 if (*sock).tx_buffer != (0 as ptr<u8>) {
2306 pmm_free_blocks((*sock).tx_buffer as u64, 2);
2307 (*sock).tx_buffer = 0 as ptr<u8>;
2308 }
2309 }
2310 spin_unlock(&((*sock).lock));
2311 }
2312
2313 fn tcp_bind(sock: ptr<TcpSocket>, port: u16) {
2314 spin_lock(&((*sock).lock));
2315 (*sock).local_port = port;
2316 spin_unlock(&((*sock).lock));
2317 }
2318
2319 fn tcp_listen(sock: ptr<TcpSocket>) {
2320 spin_lock(&((*sock).lock));
2321 (*sock).state = TCP_STATE_LISTEN;
2322 spin_unlock(&((*sock).lock));
2323 }
2324
2325 struct Fat32ExtBPB {
2326 jmp: [u8; 3],
2327 oem_name: [u8; 8],
2328 bytes_per_sector: u16,
2329 sectors_per_cluster: u8,
2330 reserved_sector_count: u16,
2331 num_fats: u8,
2332 root_entry_count: u16,
2333 total_sectors_16: u16,
2334 media_type: u8,
2335 table_size_16: u16,
2336 sectors_per_track: u16,
2337 head_side_count: u16,
2338 hidden_sector_count: u32,
2339 total_sectors_32: u32,
2340 table_size_32: u32,
2341 extended_flags: u16,
2342 fat_version: u16,
2343 root_cluster: u32,
2344 fat_info: u16,
2345 backup_boot_sector: u16,
2346 reserved_0: [u8; 12],
2347 drive_number: u8,
2348 reserved_1: u8,
2349 boot_signature: u8,
2350 volume_id: u32,
2351 volume_label: [u8; 11],
2352 fat_type_label: [u8; 8],
2353 }
2354
2355 struct Fat32DirEntry {
2356 name: [u8; 11],
2357 attr: u8,
2358 nt_res: u8,
2359 crt_time_tenth: u8,
2360 crt_time: u16,
2361 crt_date: u16,
2362 lst_acc_date: u16,
2363 fst_clus_hi: u16,
2364 wrt_time: u16,
2365 wrt_date: u16,
2366 fst_clus_lo: u16,
2367 file_size: u32,
2368 }
2369
2370 let mut fat32_lba_start: u32 = 0;
2371 let mut fat32_fat_start: u32 = 0;
2372 let mut fat32_data_start: u32 = 0;
2373 let mut fat32_root_cluster: u32 = 0;
2374 let mut fat32_sectors_per_cluster: u32 = 0;
2375 let mut fat32_bytes_per_sector: u32 = 0;
2376
2377 fn fat32_init(lba_offset: u32) {
2378 fat32_lba_start = lba_offset;
2379 let bpb_buf = pmm_alloc_blocks(1) as ptr<u8>;
2380 ata_read_sectors(fat32_lba_start, 1, bpb_buf);
2381 let bpb = bpb_buf as ptr<Fat32ExtBPB>;
2382 fat32_bytes_per_sector = (*bpb).bytes_per_sector as u32;
2383 fat32_sectors_per_cluster = (*bpb).sectors_per_cluster as u32;
2384 fat32_fat_start = fat32_lba_start + (*bpb).reserved_sector_count as u32;
2385 let fat_size = (*bpb).table_size_32;
2386 fat32_data_start = fat32_fat_start + ((*bpb).num_fats as u32 * fat_size);
2387 fat32_root_cluster = (*bpb).root_cluster;
2388 pmm_free_blocks(bpb_buf as u64, 1);
2389 }
2390
2391 fn fat32_cluster_to_lba(cluster: u32) -> u32 {
2392 return fat32_data_start + ((cluster - 2) * fat32_sectors_per_cluster);
2393 }
2394
2395 fn fat32_read_next_cluster(cluster: u32) -> u32 {
2396 let fat_offset = cluster * 4;
2397 let fat_sector = fat32_fat_start + (fat_offset / fat32_bytes_per_sector);
2398 let ent_offset = fat_offset % fat32_bytes_per_sector;
2399 let buf = pmm_alloc_blocks(1) as ptr<u8>;
2400 ata_read_sectors(fat_sector, 1, buf);
2401 let next_cluster = *((buf as u64 + ent_offset as u64) as ptr<u32>) & 0x0FFFFFFF;
2402 pmm_free_blocks(buf as u64, 1);
2403 return next_cluster;
2404 }
2405
2406 fn fat32_find_file(dir_cluster: u32, filename: ptr<u8>) -> ptr<Fat32DirEntry> {
2407 let mut current_cluster = dir_cluster;
2408 let cluster_bytes = fat32_sectors_per_cluster * fat32_bytes_per_sector;
2409 let cluster_blocks = (cluster_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
2410 let buf = pmm_alloc_blocks(cluster_blocks as u64) as ptr<u8>;
2411
2412 while current_cluster >= 2 && current_cluster < 0x0FFFFFF8 {
2413 let cluster_lba = fat32_cluster_to_lba(current_cluster);
2414 ata_read_sectors(cluster_lba, fat32_sectors_per_cluster, buf);
2415 let total_entries = cluster_bytes / 32;
2416
2417 for i in 0..total_entries {
2418 let entry = (buf as u64 + (i * 32) as u64) as ptr<Fat32DirEntry>;
2419 if (*entry).name[0] == 0x00 {
2420 pmm_free_blocks(buf as u64, cluster_blocks as u64);
2421 return 0 as ptr<Fat32DirEntry>;
2422 }
2423 if (*entry).name[0] != 0xE5 && ((*entry).attr & 0x0F) != 0x0F {
2424 let mut match_found = true;
2425 for j in 0..11 {
2426 if (*entry).name[j as usize] != *(filename + j) {
2427 match_found = false;
2428 break;
2429 }
2430 }
2431 if match_found {
2432 let ret_entry = pmm_alloc_blocks(1) as ptr<Fat32DirEntry>;
2433 memcpy(ret_entry as ptr<u8>, entry as ptr<u8>, 32);
2434 pmm_free_blocks(buf as u64, cluster_blocks as u64);
2435 return ret_entry;
2436 }
2437 }
2438 }
2439 current_cluster = fat32_read_next_cluster(current_cluster);
2440 }
2441
2442 pmm_free_blocks(buf as u64, cluster_blocks as u64);
2443 return 0 as ptr<Fat32DirEntry>;
2444 }
2445
2446 fn acpi_get_pm1_control() -> (u32, u32) {
2447 if acpi_fadt == 0 as ptr<FADTHeader> { return (0, 0); }
2448 let pm1a = (*acpi_fadt).pm1a_control_block;
2449 let pm1b = (*acpi_fadt).pm1b_control_block;
2450 return (pm1a, pm1b);
2451 }
2452
2453 fn acpi_power_off() {
2454 let (pm1a, pm1b) = acpi_get_pm1_control();
2455 if pm1a != 0 {
2456 let val = inw(pm1a as u16);
2457 outw(pm1a as u16, val | (5 << 10) | (1 << 13));
2458 }
2459 if pm1b != 0 {
2460 let val = inw(pm1b as u16);
2461 outw(pm1b as u16, val | (5 << 10) | (1 << 13));
2462 }
2463 cpu_cli();
2464 loop { cpu_hlt(); }
2465 }
2466
2467 fn acpi_reset() {
2468 let reset_reg = 0x64;
2469 let reset_cmd = 0xFE;
2470 while (inb(reset_reg) & 2) != 0 { cpu_pause(); }
2471 outb(reset_reg, reset_cmd);
2472 cpu_cli();
2473 loop { cpu_hlt(); }
2474 }
2475
2476 fn gui_draw_checkbox(win: ptr<CompositorWindow>, x: u32, y: u32, checked: bool, label: ptr<u8>) {
2477 comp_draw_rect(win, x, y, 16, 16, 0xFFFFFF);
2478 comp_draw_rect(win, x+1, y+1, 14, 14, 0x222222);
2479 if checked {
2480 comp_draw_rect(win, x+4, y+4, 8, 8, 0x00FF00);
2481 }
2482 gui_draw_string(win, label, x + 24, y, 0xFFFFFF, 0xFFFFFFFF);
2483 }
2484
2485 fn gui_draw_radio(win: ptr<CompositorWindow>, x: u32, y: u32, selected: bool, label: ptr<u8>) {
2486 comp_draw_rect(win, x, y, 16, 16, 0x888888);
2487 comp_draw_rect(win, x+2, y+2, 12, 12, 0x222222);
2488 if selected {
2489 comp_draw_rect(win, x+5, y+5, 6, 6, 0x00AFFF);
2490 }
2491 gui_draw_string(win, label, x + 24, y, 0xFFFFFF, 0xFFFFFFFF);
2492 }
2493
2494 fn gui_draw_progressbar(win: ptr<CompositorWindow>, x: u32, y: u32, w: u32, h: u32, progress: u32, max: u32) {
2495 comp_draw_rect(win, x, y, w, h, 0x444444);
2496 comp_draw_rect(win, x+1, y+1, w-2, h-2, 0x111111);
2497 let mut fill_w = 0;
2498 if max > 0 {
2499 fill_w = (progress * (w - 2)) / max;
2500 }
2501 if fill_w > 0 {
2502 comp_draw_rect(win, x+1, y+1, fill_w, h-2, 0x00FF00);
2503 }
2504 }
2505
2506 fn gui_draw_slider(win: ptr<CompositorWindow>, x: u32, y: u32, w: u32, val: u32, max: u32) {
2507 let h = 10;
2508 comp_draw_rect(win, x, y + 4, w, 2, 0x888888);
2509 let mut pos_x = 0;
2510 if max > 0 {
2511 pos_x = (val * w) / max;
2512 }
2513 if pos_x > w - 8 { pos_x = w - 8; }
2514 comp_draw_rect(win, x + pos_x, y, 8, h, 0xFFFFFF);
2515 }
2516
2517 struct AudioMixerChannel {
2518 is_playing: bool,
2519 buffer: ptr<u8>,
2520 length: u32,
2521 position: u32,
2522 volume: u8,
2523 sample_rate: u32,
2524 }
2525
2526 let mut global_audio_mixer: [AudioMixerChannel; 16];
2527
2528 fn mixer_init() {
2529 for i in 0..16 {
2530 global_audio_mixer[i].is_playing = false;
2531 global_audio_mixer[i].position = 0;
2532 global_audio_mixer[i].volume = 128;
2533 }
2534 }
2535
2536 fn mixer_play_pcm(buffer: ptr<u8>, length: u32, rate: u32) -> i32 {
2537 for i in 0..16 {
2538 if !global_audio_mixer[i].is_playing {
2539 global_audio_mixer[i].buffer = buffer;
2540 global_audio_mixer[i].length = length;
2541 global_audio_mixer[i].position = 0;
2542 global_audio_mixer[i].sample_rate = rate;
2543 global_audio_mixer[i].is_playing = true;
2544 return i as i32;
2545 }
2546 }
2547 return -1;
2548 }
2549
2550 fn mixer_stop_channel(channel: u32) {
2551 if channel < 16 {
2552 global_audio_mixer[channel as usize].is_playing = false;
2553 }
2554 }
2555
2556 fn mixer_process_frame(output_buffer: ptr<u16>, frames: u32) {
2557 for f in 0..frames {
2558 let mut mixed_sample_l: i32 = 0;
2559 let mut mixed_sample_r: i32 = 0;
2560 for c in 0..16 {
2561 let ch = &mut global_audio_mixer[c];
2562 if (*ch).is_playing && ((*ch).position * 4) < (*ch).length {
2563 let sample_ptr = ((*ch).buffer as u64 + (*ch).position as u64 * 4) as ptr<i16>;
2564 let left = (*sample_ptr as i32 * (*ch).volume as i32) / 255;
2565 let right = (*(sample_ptr as u64 + 2) as ptr<i16> as i32 * (*ch).volume as i32) / 255;
2566 mixed_sample_l += left;
2567 mixed_sample_r += right;
2568 (*ch).position += 1;
2569 } else if (*ch).is_playing {
2570 (*ch).is_playing = false;
2571 }
2572 }
2573 if mixed_sample_l > 32767 { mixed_sample_l = 32767; }
2574 if mixed_sample_l < -32768 { mixed_sample_l = -32768; }
2575 if mixed_sample_r > 32767 { mixed_sample_r = 32767; }
2576 if mixed_sample_r < -32768 { mixed_sample_r = -32768; }
2577
2578 let out_ptr = (output_buffer as u64 + f as u64 * 4) as ptr<i16>;
2579 *out_ptr = mixed_sample_l as i16;
2580 *(out_ptr as u64 + 2) as ptr<i16> = mixed_sample_r as i16;
2581 }
2582 }
2583
2584 let mut usb_hid_kbd_map: [u8; 128] = [
2585 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,
2586 '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,
2587 '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,
2588 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,
2589 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,
2590 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
2591 ];
2592 let mut usb_hid_shift_map: [u8; 128] = [
2593 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,
2594 '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,
2595 '!' as u8, '@' as u8, '#' as u8, '$' as u8, '%' as u8, '^' as u8, '&' as u8, '*' as u8, '(' as u8, ')' as u8,
2596 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,
2597 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,
2598 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
2599 ];
2600
2601 struct UsbDeviceDescriptor {
2602 length: u8,
2603 descriptor_type: u8,
2604 bcd_usb: u16,
2605 device_class: u8,
2606 device_subclass: u8,
2607 device_protocol: u8,
2608 max_packet_size: u8,
2609 id_vendor: u16,
2610 id_product: u16,
2611 bcd_device: u16,
2612 manufacturer: u8,
2613 product: u8,
2614 serial_number: u8,
2615 num_configurations: u8,
2616 }
2617
2618 struct UsbEndpointDescriptor {
2619 length: u8,
2620 descriptor_type: u8,
2621 endpoint_address: u8,
2622 attributes: u8,
2623 max_packet_size: u16,
2624 interval: u8,
2625 }
2626
2627 struct HidReport {
2628 modifier: u8,
2629 reserved: u8,
2630 keys: [u8; 6],
2631 }
2632
2633 struct MouseReport {
2634 buttons: u8,
2635 x: i8,
2636 y: i8,
2637 wheel: i8,
2638 }
2639
2640 let mut global_kbd_state_shift: bool = false;
2641 let mut global_kbd_state_caps: bool = false;
2642
2643 fn usb_hid_parse_keyboard(report: ptr<HidReport>) {
2644 let m = (*report).modifier;
2645 global_kbd_state_shift = (m & 0x02) != 0 || (m & 0x20) != 0;
2646
2647 for i in 0..6 {
2648 let k = (*report).keys[i];
2649 if k >= 4 && k <= 100 {
2650 let mut ascii = usb_hid_kbd_map[k as usize];
2651 if global_kbd_state_shift != global_kbd_state_caps {
2652 if k >= 4 && k <= 29 { ascii = usb_hid_shift_map[k as usize]; }
2653 }
2654 if global_kbd_state_shift && (k < 4 || k > 29) {
2655 ascii = usb_hid_shift_map[k as usize];
2656 }
2657 if ascii != 0 {
2658 kbd_buf[kbd_wp as usize] = ascii;
2659 kbd_wp = (kbd_wp + 1) % 1024;
2660 }
2661 }
2662 }
2663 }
2664
2665 fn usb_hid_parse_mouse(report: ptr<MouseReport>) {
2666 let btn = (*report).buttons;
2667 let dx = (*report).x as i32;
2668 let dy = (*report).y as i32;
2669
2670 mouse_x = mouse_x + dx;
2671 mouse_y = mouse_y + dy;
2672
2673 if mouse_x < 0 { mouse_x = 0; }
2674 if mouse_y < 0 { mouse_y = 0; }
2675 if mouse_x >= comp_width as i32 { mouse_x = comp_width as i32 - 1; }
2676 if mouse_y >= comp_height as i32 { mouse_y = comp_height as i32 - 1; }
2677
2678 mouse_b = btn;
2679 }
2680
2681 const SWAP_MAGIC: u64 = 0x5357415053504143;
2682 const MAX_SWAP_PAGES: u64 = 262144;
2683
2684 struct SwapHeader {
2685 magic: u64,
2686 total_pages: u64,
2687 free_pages: u64,
2688 bitmap_offset: u64,
2689 }
2690
2691 struct PageFrameInfo {
2692 phys_addr: u64,
2693 virt_addr: u64,
2694 pid: u64,
2695 access_time: u64,
2696 flags: u32,
2697 swap_idx: u64,
2698 }
2699
2700 let mut swap_bitmap: ptr<u64>;
2701 let mut pfn_database: ptr<PageFrameInfo>;
2702 let mut pfn_count: u64 = 0;
2703 let mut current_time_tick: u64 = 0;
2704 let mut swap_lck: Spinlock;
2705
2706 fn swap_init() {
2707 spin_init(&swap_lck);
2708 let bitmap_sz = MAX_SWAP_PAGES / 64 * 8;
2709 swap_bitmap = pmm_alloc_blocks(bitmap_sz / PAGE_SIZE + 1) as ptr<u64>;
2710 memset(swap_bitmap as ptr<u8>, 0, bitmap_sz);
2711
2712 let pfn_sz = (MAX_MEM_MB * 1024 * 1024) / PAGE_SIZE * sizeof(PageFrameInfo) as u64;
2713 pfn_database = pmm_alloc_blocks(pfn_sz / PAGE_SIZE + 1) as ptr<PageFrameInfo>;
2714 memset(pfn_database as ptr<u8>, 0, pfn_sz);
2715 }
2716
2717 fn swap_alloc_slot() -> u64 {
2718 for i in 0..(MAX_SWAP_PAGES / 64) {
2719 if *(swap_bitmap + i) != 0xFFFFFFFFFFFFFFFF {
2720 for j in 0..64 {
2721 if (*(swap_bitmap + i) & (1u64 << j)) == 0 {
2722 *(swap_bitmap + i) |= (1u64 << j);
2723 return (i * 64) + j;
2724 }
2725 }
2726 }
2727 }
2728 return 0xFFFFFFFFFFFFFFFF;
2729 }
2730
2731 fn swap_free_slot(idx: u64) {
2732 *(swap_bitmap + (idx / 64)) &= !(1u64 << (idx % 64));
2733 }
2734
2735 fn page_replacement_lru() -> ptr<PageFrameInfo> {
2736 let mut oldest_time: u64 = 0xFFFFFFFFFFFFFFFF;
2737 let mut victim: ptr<PageFrameInfo> = 0 as ptr<PageFrameInfo>;
2738
2739 for i in 0..pfn_count {
2740 let frame = (pfn_database as u64 + i * sizeof(PageFrameInfo) as u64) as ptr<PageFrameInfo>;
2741 if ((*frame).flags & 1) != 0 && ((*frame).flags & 2) == 0 {
2742 if (*frame).access_time < oldest_time {
2743 oldest_time = (*frame).access_time;
2744 victim = frame;
2745 }
2746 }
2747 }
2748 return victim;
2749 }
2750
2751 fn swap_page_out(frame: ptr<PageFrameInfo>) -> bool {
2752 spin_lock(&swap_lck);
2753 let slot = swap_alloc_slot();
2754 if slot == 0xFFFFFFFFFFFFFFFF {
2755 spin_unlock(&swap_lck);
2756 return false;
2757 }
2758
2759 let disk_lba = 1000000 + (slot * 8);
2760 ata_write_sectors(disk_lba as u32, 8, (*frame).phys_addr as ptr<u8>);
2761
2762 (*frame).swap_idx = slot;
2763 (*frame).flags &= !1;
2764 vmm_unmap_page((*frame).virt_addr);
2765 cpu_invlpg((*frame).virt_addr);
2766
2767 pmm_free_blocks((*frame).phys_addr, 1);
2768 (*frame).phys_addr = 0;
2769
2770 spin_unlock(&swap_lck);
2771 return true;
2772 }
2773
2774 fn swap_page_in(frame: ptr<PageFrameInfo>) {
2775 spin_lock(&swap_lck);
2776 let mut phys = pmm_alloc_blocks(1);
2777 if phys == 0 {
2778 let victim = page_replacement_lru();
2779 if victim != (0 as ptr<PageFrameInfo>) {
2780 swap_page_out(victim);
2781 phys = pmm_alloc_blocks(1);
2782 }
2783 }
2784
2785 let disk_lba = 1000000 + ((*frame).swap_idx * 8);
2786 ata_read_sectors(disk_lba as u32, 8, phys as ptr<u8>);
2787
2788 (*frame).phys_addr = phys;
2789 (*frame).flags |= 1;
2790 (*frame).access_time = current_time_tick;
2791
2792 vmm_map_page(phys, (*frame).virt_addr, 0x07);
2793 cpu_invlpg((*frame).virt_addr);
2794
2795 swap_free_slot((*frame).swap_idx);
2796 (*frame).swap_idx = 0xFFFFFFFFFFFFFFFF;
2797 spin_unlock(&swap_lck);
2798 }
2799
2800 fn page_fault_handler_adv(cr2: u64, err_code: u64) {
2801 let virt_align = cr2 & !(PAGE_SIZE - 1);
2802 for i in 0..pfn_count {
2803 let frame = (pfn_database as u64 + i * sizeof(PageFrameInfo) as u64) as ptr<PageFrameInfo>;
2804 if (*frame).virt_addr == virt_align && ((*frame).flags & 1) == 0 {
2805 swap_page_in(frame);
2806 return;
2807 }
2808 }
2809 cpu_cli();
2810 loop { cpu_hlt(); }
2811 }
2812
2813 struct Vec3 { x: f32, y: f32, z: f32, w: f32 }
2814 struct Mat4 { m: [[f32; 4]; 4] }
2815
2816 fn math_abs(a: f32) -> f32 { if a < 0.0 { return -a; } return a; }
2817
2818 fn math_fmod(a: f32, b: f32) -> f32 {
2819 let mut res = a;
2820 while res >= b { res = res - b; }
2821 while res < 0.0 { res = res + b; }
2822 return res;
2823 }
2824
2825 fn taylor_sin(mut x: f32) -> f32 {
2826 let PI2 = 6.28318530718;
2827 x = math_fmod(x, PI2);
2828 if x > 3.14159265 { x = x - PI2; }
2829 let x2 = x * x;
2830 let x3 = x2 * x;
2831 let x5 = x3 * x2;
2832 let x7 = x5 * x2;
2833 return x - (x3 / 6.0) + (x5 / 120.0) - (x7 / 5040.0);
2834 }
2835
2836 fn taylor_cos(mut x: f32) -> f32 {
2837 let PI2 = 6.28318530718;
2838 x = math_fmod(x, PI2);
2839 if x > 3.14159265 { x = x - PI2; }
2840 let x2 = x * x;
2841 let x4 = x2 * x2;
2842 let x6 = x4 * x2;
2843 return 1.0 - (x2 / 2.0) + (x4 / 24.0) - (x6 / 720.0);
2844 }
2845
2846 fn mat4_identity() -> Mat4 {
2847 let mut mat: Mat4;
2848 for i in 0..4 { for j in 0..4 { mat.m[i][j] = 0.0; } }
2849 mat.m[0][0] = 1.0; mat.m[1][1] = 1.0; mat.m[2][2] = 1.0; mat.m[3][3] = 1.0;
2850 return mat;
2851 }
2852
2853 fn mat4_mul(a: ptr<Mat4>, b: ptr<Mat4>) -> Mat4 {
2854 let mut res: Mat4;
2855 for c in 0..4 {
2856 for r in 0..4 {
2857 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];
2858 }
2859 }
2860 return res;
2861 }
2862
2863 fn mat4_make_rot_x(angle: f32) -> Mat4 {
2864 let mut mat = mat4_identity();
2865 let c = taylor_cos(angle); let s = taylor_sin(angle);
2866 mat.m[1][1] = c; mat.m[1][2] = -s;
2867 mat.m[2][1] = s; mat.m[2][2] = c;
2868 return mat;
2869 }
2870
2871 fn mat4_make_rot_y(angle: f32) -> Mat4 {
2872 let mut mat = mat4_identity();
2873 let c = taylor_cos(angle); let s = taylor_sin(angle);
2874 mat.m[0][0] = c; mat.m[0][2] = s;
2875 mat.m[2][0] = -s; mat.m[2][2] = c;
2876 return mat;
2877 }
2878
2879 fn mat4_make_rot_z(angle: f32) -> Mat4 {
2880 let mut mat = mat4_identity();
2881 let c = taylor_cos(angle); let s = taylor_sin(angle);
2882 mat.m[0][0] = c; mat.m[0][1] = -s;
2883 mat.m[1][0] = s; mat.m[1][1] = c;
2884 return mat;
2885 }
2886
2887 fn mat4_make_proj(fov: f32, aspect: f32, near: f32, far: f32) -> Mat4 {
2888 let half_fov = fov * 0.5;
2889 let f = taylor_cos(half_fov) / taylor_sin(half_fov);
2890 let mut mat = mat4_identity();
2891 mat.m[0][0] = f / aspect;
2892 mat.m[1][1] = f;
2893 mat.m[2][2] = (-far - near) / (near - far);
2894 mat.m[2][3] = (2.0 * far * near) / (near - far);
2895 mat.m[3][2] = 1.0;
2896 mat.m[3][3] = 0.0;
2897 return mat;
2898 }
2899
2900 fn mat4_multiply_vec(m: ptr<Mat4>, i: ptr<Vec3>) -> Vec3 {
2901 let mut v: Vec3;
2902 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];
2903 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];
2904 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];
2905 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];
2906 return v;
2907 }
2908
2909 struct Triangle3D { p: [Vec3; 3], color: u32 }
2910 struct Mesh3D { tris: ptr<Triangle3D>, count: u32 }
2911
2912 let mut z_buffer: ptr<f32>;
2913
2914 fn render_init_3d(w: u32, h: u32) {
2915 z_buffer = pmm_alloc_blocks((w * h * 4) / PAGE_SIZE + 1) as ptr<f32>;
2916 }
2917
2918 fn render_clear_z_buffer(w: u32, h: u32) {
2919 let z_ptr = z_buffer as ptr<f32>;
2920 let total = w * h;
2921 for i in 0..total {
2922 *(z_ptr + i as usize) = 0.0;
2923 }
2924 }
2925
2926 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) {
2927 let mut min_y = y0; if y1 < min_y { min_y = y1; } if y2 < min_y { min_y = y2; }
2928 let mut max_y = y0; if y1 > max_y { max_y = y1; } if y2 > max_y { max_y = y2; }
2929 let mut min_x = x0; if x1 < min_x { min_x = x1; } if x2 < min_x { min_x = x2; }
2930 let mut max_x = x0; if x1 > max_x { max_x = x1; } if x2 > max_x { max_x = x2; }
2931
2932 if min_x < 0 { min_x = 0; }
2933 if min_y < 0 { min_y = 0; }
2934 if max_x >= (*win).width as i32 { max_x = (*win).width as i32 - 1; }
2935 if max_y >= (*win).height as i32 { max_y = (*win).height as i32 - 1; }
2936
2937 let buf = (*win).buffer_phys as ptr<u32>;
2938 let z_ptr = z_buffer;
2939 let win_w = (*win).width as i32;
2940
2941 let denom = ((y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2)) as f32;
2942 if denom == 0.0 { return; }
2943 let inv_denom = 1.0 / denom;
2944
2945 for y in min_y..=max_y {
2946 for x in min_x..=max_x {
2947 let b0 = (((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2)) as f32) * inv_denom;
2948 let b1 = (((y2 - y0) * (x - x2) + (x0 - x2) * (y - y2)) as f32) * inv_denom;
2949 let b2 = 1.0 - b0 - b1;
2950
2951 if b0 >= 0.0 && b1 >= 0.0 && b2 >= 0.0 {
2952 let z_inv = z0 * b0 + z1 * b1 + z2 * b2;
2953 let z_idx = (y * win_w + x) as u64;
2954 let current_z = (z_ptr as u64 + z_idx * 4) as ptr<f32>;
2955
2956 if z_inv > *current_z {
2957 *current_z = z_inv;
2958 *(buf + z_idx as usize) = color;
2959 }
2960 }
2961 }
2962 }
2963 }
2964
2965 fn render_mesh(win: ptr<CompositorWindow>, mesh: ptr<Mesh3D>, mat_world: ptr<Mat4>, mat_proj: ptr<Mat4>) {
2966 let half_w = (*win).width as f32 * 0.5;
2967 let half_h = (*win).height as f32 * 0.5;
2968
2969 for i in 0..(*mesh).count {
2970 let tri = ((*mesh).tris as u64 + i as u64 * sizeof(Triangle3D) as u64) as ptr<Triangle3D>;
2971 let mut tri_trans: Triangle3D;
2972 let mut tri_proj: Triangle3D;
2973 let mut inv_w: [f32; 3] = [0.0, 0.0, 0.0];
2974
2975 for j in 0..3 {
2976 tri_trans.p[j] = mat4_multiply_vec(mat_world, &(*tri).p[j] as ptr<Vec3>);
2977 tri_proj.p[j] = mat4_multiply_vec(mat_proj, &tri_trans.p[j] as ptr<Vec3>);
2978
2979 if tri_proj.p[j].w <= 0.0001 { continue; }
2980 inv_w[j] = 1.0 / tri_proj.p[j].w;
2981
2982 tri_proj.p[j].x *= inv_w[j];
2983 tri_proj.p[j].y *= inv_w[j];
2984 tri_proj.p[j].z *= inv_w[j];
2985
2986 tri_proj.p[j].x = (tri_proj.p[j].x + 1.0) * half_w;
2987 tri_proj.p[j].y = (1.0 - tri_proj.p[j].y) * half_h;
2988 }
2989
2990 let v0 = &tri_trans.p[0];
2991 let v1 = &tri_trans.p[1];
2992 let v2 = &tri_trans.p[2];
2993
2994 let norm_x = (v1.y - v0.y) * (v2.z - v0.z) - (v1.z - v0.z) * (v2.y - v0.y);
2995 let norm_y = (v1.z - v0.z) * (v2.x - v0.x) - (v1.x - v0.x) * (v2.z - v0.z);
2996 let norm_z = (v1.x - v0.x) * (v2.y - v0.y) - (v1.y - v0.y) * (v2.x - v0.x);
2997
2998 let dot = norm_x * v0.x + norm_y * v0.y + norm_z * v0.z;
2999
3000 if dot < 0.0 {
3001 let shade = math_abs(norm_z) * 255.0;
3002 let c_r = ((((*tri).color >> 16) & 0xFF) as f32 * shade / 255.0) as u32;
3003 let c_g = ((((*tri).color >> 8) & 0xFF) as f32 * shade / 255.0) as u32;
3004 let c_b = (((*tri).color & 0xFF) as f32 * shade / 255.0) as u32;
3005 let shaded_color = (c_r << 16) | (c_g << 8) | c_b;
3006
3007 draw_flat_triangle(win,
3008 tri_proj.p[0].x as i32, tri_proj.p[0].y as i32, inv_w[0],
3009 tri_proj.p[1].x as i32, tri_proj.p[1].y as i32, inv_w[1],
3010 tri_proj.p[2].x as i32, tri_proj.p[2].y as i32, inv_w[2],
3011 shaded_color);
3012 }
3013 }
3014 }
3015
3016 let mut prng_state: u64 = 0x8817263544132211;
3017
3018 fn rand_next() -> u64 {
3019 prng_state ^= prng_state << 13;
3020 prng_state ^= prng_state >> 7;
3021 prng_state ^= prng_state << 17;
3022 return prng_state;
3023 }
3024
3025 fn rand_seed(seed: u64) {
3026 if seed != 0 { prng_state = seed; }
3027 }
3028
3029 fn strchr(str: ptr<u8>, c: u8) -> ptr<u8> {
3030 let mut i: u64 = 0;
3031 while *(str + i) != 0 {
3032 if *(str + i) == c { return (str as u64 + i) as ptr<u8>; }
3033 i = i + 1;
3034 }
3035 if c == 0 { return (str as u64 + i) as ptr<u8>; }
3036 return 0 as ptr<u8>;
3037 }
3038 fn strcat(dest: ptr<u8>, src: ptr<u8>) {
3039 let mut i: u64 = 0;
3040 while *(dest + i) != 0 { i = i + 1; }
3041 let mut j: u64 = 0;
3042 while *(src + j) != 0 {
3043 *(dest + i + j) = *(src + j);
3044 j = j + 1;
3045 }
3046 *(dest + i + j) = 0;
3047 }
3048 fn strncmp(s1: ptr<u8>, s2: ptr<u8>, n: u64) -> i32 {
3049 for i in 0..n {
3050 if *(s1 + i) == 0 || *(s1 + i) != *(s2 + i) {
3051 return (*(s1 + i) - *(s2 + i)) as i32;
3052 }
3053 }
3054 return 0;
3055 }
3056 fn atoi(str: ptr<u8>) -> i32 {
3057 let mut res: i32 = 0;
3058 let mut sign: i32 = 1;
3059 let mut i: u64 = 0;
3060 if *(str + i) == '-' as u8 {
3061 sign = -1;
3062 i = i + 1;
3063 }
3064 while *(str + i) >= '0' as u8 && *(str + i) <= '9' as u8 {
3065 res = res * 10 + (*(str + i) - '0' as u8) as i32;
3066 i = i + 1;
3067 }
3068 return res * sign;
3069 }
3070 fn itoa(val: i32, base: i32, buf: ptr<u8>) {
3071 let mut i: u64 = 0;
3072 let mut is_neg = false;
3073 let mut num = val;
3074 if num == 0 {
3075 *(buf + i) = '0' as u8;
3076 *(buf + i + 1) = 0;
3077 return;
3078 }
3079 if num < 0 && base == 10 {
3080 is_neg = true;
3081 num = -num;
3082 }
3083 while num != 0 {
3084 let rem = num % base;
3085 if rem > 9 {
3086 *(buf + i) = (rem - 10 + 'a' as i32) as u8;
3087 } else {
3088 *(buf + i) = (rem + '0' as i32) as u8;
3089 }
3090 i = i + 1;
3091 num = num / base;
3092 }
3093 if is_neg {
3094 *(buf + i) = '-' as u8;
3095 i = i + 1;
3096 }
3097 *(buf + i) = 0;
3098 let mut start: u64 = 0;
3099 let mut end: u64 = i - 1;
3100 while start < end {
3101 let temp = *(buf + start);
3102 *(buf + start) = *(buf + end);
3103 *(buf + end) = temp;
3104 start = start + 1;
3105 end = end - 1;
3106 }
3107 }
3108 let mut b64_table: ptr<u8> = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" as ptr<u8>;
3109 fn base64_encode(src: ptr<u8>, len: u64, out: ptr<u8>) {
3110 let mut i: u64 = 0;
3111 let mut j: u64 = 0;
3112 while i < len {
3113 let octet_a = if i < len { *(src + i) } else { 0 };
3114 let octet_b = if i + 1 < len { *(src + i + 1) } else { 0 };
3115 let octet_c = if i + 2 < len { *(src + i + 2) } else { 0 };
3116 let triple = ((octet_a as u32) << 16) + ((octet_b as u32) << 8) + (octet_c as u32);
3117 *(out + j) = *(b64_table + ((triple >> 18) & 0x3F) as u64);
3118 *(out + j + 1) = *(b64_table + ((triple >> 12) & 0x3F) as u64);
3119 *(out + j + 2) = if i + 1 < len { *(b64_table + ((triple >> 6) & 0x3F) as u64) } else { '=' as u8 };
3120 *(out + j + 3) = if i + 2 < len { *(b64_table + (triple & 0x3F) as u64) } else { '=' as u8 };
3121 i = i + 3;
3122 j = j + 4;
3123 }
3124 *(out + j) = 0;
3125 }
3126 fn tcp_accept(sock: ptr<TcpSocket>) -> ptr<TcpSocket> {
3127 spin_lock(&((*sock).lock));
3128 if (*sock).state == TCP_STATE_SYN_RCVD {
3129 let new_sock = tcp_create_socket();
3130 if new_sock != 0 as ptr<TcpSocket> {
3131 (*new_sock).state = TCP_STATE_ESTABLISHED;
3132 (*new_sock).local_port = (*sock).local_port;
3133 (*new_sock).remote_port = (*sock).remote_port;
3134 (*new_sock).remote_ip = (*sock).remote_ip;
3135 (*new_sock).seq_num = (*sock).seq_num;
3136 (*new_sock).ack_num = (*sock).ack_num;
3137 (*sock).state = TCP_STATE_LISTEN;
3138 spin_unlock(&((*sock).lock));
3139 return new_sock;
3140 }
3141 }
3142 spin_unlock(&((*sock).lock));
3143 return 0 as ptr<TcpSocket>;
3144 }
3145 fn tcp_receive(sock: ptr<TcpSocket>, buffer: ptr<u8>, max_len: u32) -> u32 {
3146 spin_lock(&((*sock).lock));
3147 let mut bytes_read: u32 = 0;
3148 while (*sock).rx_head != (*sock).rx_tail && bytes_read < max_len {
3149 *(buffer + bytes_read as u64) = *((*sock).rx_buffer as u64 + (*sock).rx_tail as u64) as ptr<u8>;
3150 (*sock).rx_tail = ((*sock).rx_tail + 1) % (PAGE_SIZE as u32 * 2);
3151 bytes_read = bytes_read + 1;
3152 }
3153 spin_unlock(&((*sock).lock));
3154 return bytes_read;
3155 }
3156 fn tcp_send_data(sock: ptr<TcpSocket>, data: ptr<u8>, len: u32) {
3157 spin_lock(&((*sock).lock));
3158 if (*sock).state == TCP_STATE_ESTABLISHED {
3159 tcp_send_segment(sock, 0x0018, data, len as u16);
3160 (*sock).seq_num = (*sock).seq_num + len;
3161 }
3162 spin_unlock(&((*sock).lock));
3163 }
3164 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>;
3165 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>;
3166 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>;
3167 fn http_handle_client(client_sock: ptr<TcpSocket>) {
3168 let req_buf = pmm_alloc_blocks(1) as ptr<u8>;
3169 memset(req_buf, 0, PAGE_SIZE);
3170 let mut wait_timeout = 10000;
3171 let mut req_len: u32 = 0;
3172 while wait_timeout > 0 {
3173 let r = tcp_receive(client_sock, (req_buf as u64 + req_len as u64) as ptr<u8>, PAGE_SIZE as u32 - req_len);
3174 req_len = req_len + r;
3175 if req_len > 4 {
3176 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 {
3177 break;
3178 }
3179 }
3180 wait_timeout = wait_timeout - 1;
3181 cpu_pause();
3182 }
3183
3184 if req_len > 0 {
3185 if strncmp(req_buf, "GET / " as ptr<u8>, 6) == 0 {
3186 let res_buf = pmm_alloc_blocks(2) as ptr<u8>;
3187 memset(res_buf, 0, PAGE_SIZE * 2);
3188 strcpy(res_buf, http_200_hdr);
3189 strcat(res_buf, http_index_html);
3190 tcp_send_data(client_sock, res_buf, strlen(res_buf) as u32);
3191 pmm_free_blocks(res_buf as u64, 2);
3192 } else {
3193 let res_buf = pmm_alloc_blocks(1) as ptr<u8>;
3194 memset(res_buf, 0, PAGE_SIZE);
3195 strcpy(res_buf, http_404_hdr);
3196 strcat(res_buf, "<html><body><h1>404 File Not Found</h1></body></html>" as ptr<u8>);
3197 tcp_send_data(client_sock, res_buf, strlen(res_buf) as u32);
3198 pmm_free_blocks(res_buf as u64, 1);
3199 }
3200 }
3201
3202 tcp_close(client_sock);
3203 pmm_free_blocks(req_buf as u64, 1);
3204 (*current_process).state = 0;
3205 scheduler_tick();
3206 }
3207 fn http_server_task() {
3208 let server_sock = tcp_create_socket();
3209 tcp_bind(server_sock, 80);
3210 tcp_listen(server_sock);
3211
3212 loop {
3213 let client_sock = tcp_accept(server_sock);
3214 if client_sock != 0 as ptr<TcpSocket> {
3215 let proc = create_process(http_handle_client as u64, true);
3216 let ctx = (*proc).context;
3217 (*ctx).rdi = client_sock as u64;
3218 }
3219 scheduler_tick();
3220 }
3221 }
3222 struct ShellCtx {
3223 win: ptr<CompositorWindow>,
3224 cx: u32,
3225 cy: u32,
3226 buf: [u8; 512],
3227 pos: u32,
3228 cwd: [u8; 256],
3229 fg_color: u32,
3230 }
3231 let mut global_shell: ptr<ShellCtx>;
3232 fn shell_print_char(c: u8) {
3233 if c == 10 {
3234 (*global_shell).cx = 2;
3235 (*global_shell).cy = (*global_shell).cy + system_font_h + 2;
3236 } else if c == 8 {
3237 if (*global_shell).cx > 2 {
3238 (*global_shell).cx = (*global_shell).cx - system_font_w;
3239 gui_draw_char((*global_shell).win, ' ' as u8, (*global_shell).cx, (*global_shell).cy, (*global_shell).fg_color, 0x000000);
3240 }
3241 } else {
3242 gui_draw_char((*global_shell).win, c, (*global_shell).cx, (*global_shell).cy, (*global_shell).fg_color, 0x000000);
3243 (*global_shell).cx = (*global_shell).cx + system_font_w;
3244 if (*global_shell).cx >= (*(*global_shell).win).width - system_font_w {
3245 (*global_shell).cx = 2;
3246 (*global_shell).cy = (*global_shell).cy + system_font_h + 2;
3247 }
3248 }
3249 if (*global_shell).cy >= (*(*global_shell).win).height - system_font_h {
3250 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
3251 (*global_shell).cx = 2;
3252 (*global_shell).cy = 2;
3253 }
3254 }
3255 fn shell_print_string(str: ptr<u8>) {
3256 let mut i: u64 = 0;
3257 while *(str + i) != 0 {
3258 shell_print_char(*(str + i));
3259 i = i + 1;
3260 }
3261 }
3262 fn shell_draw_prompt() {
3263 (*global_shell).fg_color = 0x00FF00;
3264 shell_print_string("root@aegis-x:" as ptr<u8>);
3265 (*global_shell).fg_color = 0x00AFFF;
3266 shell_print_string(&((*global_shell).cwd[0]) as ptr<u8>);
3267 (*global_shell).fg_color = 0xFFFFFF;
3268 shell_print_string("# " as ptr<u8>);
3269 }
3270 fn shell_cmd_clear() {
3271 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
3272 (*global_shell).cx = 2;
3273 (*global_shell).cy = 2;
3274 }
3275 fn shell_cmd_help() {
3276 shell_print_string("Aegis-X Shell v1.0\n" as ptr<u8>);
3277 shell_print_string("Commands: help, clear, echo, ls, cat, uptime, reboot, poweroff\n" as ptr<u8>);
3278 }
3279 fn shell_cmd_echo(args: ptr<u8>) {
3280 shell_print_string(args);
3281 shell_print_char(10);
3282 }
3283 fn shell_cmd_uptime() {
3284 let mut buf: [u8; 32];
3285 let ticks = rtc_tick;
3286 shell_print_string("Uptime: " as ptr<u8>);
3287 itoa(ticks as i32, 10, &buf[0] as ptr<u8>);
3288 shell_print_string(&buf[0] as ptr<u8>);
3289 shell_print_string(" ticks\n" as ptr<u8>);
3290 }
3291 fn shell_cmd_ls(args: ptr<u8>) {
3292 let mut path = &((*global_shell).cwd[0]) as ptr<u8>;
3293 if *args != 0 { path = args; }
3294 let dir = vfs_find_child(global_vfs_root, path);
3295 if dir == 0 as ptr<VfsNode> {
3296 shell_print_string("ls: cannot access path\n" as ptr<u8>);
3297 return;
3298 }
3299 if ((*dir).flags & 0x07) != 0 {
3300 let mut curr = (*dir).children;
3301 while curr != 0 as ptr<VfsNode> {
3302 if ((*curr).flags & 0x07) != 0 {
3303 (*global_shell).fg_color = 0x00AFFF;
3304 } else {
3305 (*global_shell).fg_color = 0xFFFFFF;
3306 }
3307 shell_print_string(&((*curr).name[0]) as ptr<u8>);
3308 shell_print_string(" " as ptr<u8>);
3309 curr = (*curr).next;
3310 }
3311 shell_print_char(10);
3312 } else {
3313 shell_print_string(&((*dir).name[0]) as ptr<u8>);
3314 shell_print_char(10);
3315 }
3316 (*global_shell).fg_color = 0xFFFFFF;
3317 }
3318 fn shell_execute() {
3319 let mut cmd_buf: [u8; 512];
3320 memcpy(&cmd_buf[0] as ptr<u8>, &((*global_shell).buf[0]) as ptr<u8>, (*global_shell).pos as u64);
3321 cmd_buf[(*global_shell).pos as usize] = 0;
3322
3323 let mut i: u32 = 0;
3324 while cmd_buf[i as usize] != 0 && cmd_buf[i as usize] != ' ' as u8 { i = i + 1; }
3325 if cmd_buf[i as usize] == ' ' as u8 {
3326 cmd_buf[i as usize] = 0;
3327 i = i + 1;
3328 }
3329 let args = (&cmd_buf[0] as u64 + i as u64) as ptr<u8>;
3330 let cmd = &cmd_buf[0] as ptr<u8>;
3331
3332 if (*global_shell).pos > 0 {
3333 if strcmp(cmd, "help" as ptr<u8>) == 0 { shell_cmd_help(); }
3334 else if strcmp(cmd, "clear" as ptr<u8>) == 0 { shell_cmd_clear(); }
3335 else if strcmp(cmd, "echo" as ptr<u8>) == 0 { shell_cmd_echo(args); }
3336 else if strcmp(cmd, "uptime" as ptr<u8>) == 0 { shell_cmd_uptime(); }
3337 else if strcmp(cmd, "ls" as ptr<u8>) == 0 { shell_cmd_ls(args); }
3338 else if strcmp(cmd, "reboot" as ptr<u8>) == 0 { acpi_reset(); }
3339 else if strcmp(cmd, "poweroff" as ptr<u8>) == 0 { acpi_power_off(); }
3340 else {
3341 shell_print_string("Command not found: " as ptr<u8>);
3342 shell_print_string(cmd);
3343 shell_print_char(10);
3344 }
3345 }
3346
3347 (*global_shell).pos = 0;
3348 shell_draw_prompt();
3349 }
3350 fn shell_task() {
3351 let win = comp_create_window(50, 50, 800, 600, "Aegis Terminal" as ptr<u8>);
3352 comp_draw_rect(win, 0, 0, (*win).width, (*win).height, 0x000000);
3353
3354 global_shell = pmm_alloc_blocks(1) as ptr<ShellCtx>;
3355 memset(global_shell as ptr<u8>, 0, sizeof(ShellCtx) as u64);
3356 (*global_shell).win = win;
3357 (*global_shell).cx = 2;
3358 (*global_shell).cy = 2;
3359 (*global_shell).fg_color = 0xFFFFFF;
3360 strcpy(&((*global_shell).cwd[0]) as ptr<u8>, "/" as ptr<u8>);
3361
3362 shell_print_string("Welcome to YBG13 Aegis-X Terminal.\n" as ptr<u8>);
3363 shell_draw_prompt();
3364
3365 loop {
3366 let c = kbd_read();
3367 if c != 0 {
3368 if c == 10 {
3369 shell_print_char(10);
3370 shell_execute();
3371 } else if c == 8 {
3372 if (*global_shell).pos > 0 {
3373 (*global_shell).pos = (*global_shell).pos - 1;
3374 shell_print_char(8);
3375 }
3376 } else {
3377 if (*global_shell).pos < 510 {
3378 (*global_shell).buf[(*global_shell).pos as usize] = c;
3379 (*global_shell).pos = (*global_shell).pos + 1;
3380 shell_print_char(c);
3381 }
3382 }
3383 }
3384 scheduler_tick();
3385 }
3386 }
3387 struct VmaNode {
3388 start_vaddr: u64,
3389 end_vaddr: u64,
3390 flags: u32,
3391 file_node: ptr<VfsNode>,
3392 file_offset: u64,
3393 next: ptr<VmaNode>,
3394 }
3395 struct ProcessMemoryMap {
3396 vma_head: ptr<VmaNode>,
3397 brk_start: u64,
3398 brk_current: u64,
3399 stack_bottom: u64,
3400 stack_top: u64,
3401 mmap_base: u64,
3402 }
3403 fn vma_create(proc_map: ptr<ProcessMemoryMap>, start: u64, len: u64, flags: u32, file: ptr<VfsNode>, offset: u64) -> ptr<VmaNode> {
3404 let node = pmm_alloc_blocks(1) as ptr<VmaNode>;
3405 memset(node as ptr<u8>, 0, sizeof(VmaNode) as u64);
3406 (*node).start_vaddr = start;
3407 (*node).end_vaddr = start + len;
3408 (*node).flags = flags;
3409 (*node).file_node = file;
3410 (*node).file_offset = offset;
3411
3412 if (*proc_map).vma_head == 0 as ptr<VmaNode> {
3413 (*proc_map).vma_head = node;
3414 } else {
3415 let mut curr = (*proc_map).vma_head;
3416 while (*curr).next != 0 as ptr<VmaNode> {
3417 curr = (*curr).next;
3418 }
3419 (*curr).next = node;
3420 }
3421 return node;
3422 }
3423 fn vma_find_region(proc_map: ptr<ProcessMemoryMap>, vaddr: u64) -> ptr<VmaNode> {
3424 let mut curr = (*proc_map).vma_head;
3425 while curr != 0 as ptr<VmaNode> {
3426 if vaddr >= (*curr).start_vaddr && vaddr < (*curr).end_vaddr {
3427 return curr;
3428 }
3429 curr = (*curr).next;
3430 }
3431 return 0 as ptr<VmaNode>;
3432 }
3433 struct TarHeader {
3434 filename: [u8; 100],
3435 filemode: [u8; 8],
3436 owner_id: [u8; 8],
3437 group_id: [u8; 8],
3438 filesize: [u8; 12],
3439 last_mod: [u8; 12],
3440 checksum: [u8; 8],
3441 type_flag: u8,
3442 linked_file: [u8; 100],
3443 ustar_magic: [u8; 6],
3444 ustar_version: [u8; 2],
3445 owner_name: [u8; 32],
3446 group_name: [u8; 32],
3447 dev_major: [u8; 8],
3448 dev_minor: [u8; 8],
3449 prefix: [u8; 155],
3450 padding: [u8; 12],
3451 }
3452 fn tar_octal_to_int(octal_str: ptr<u8>, len: u32) -> u64 {
3453 let mut result: u64 = 0;
3454 for i in 0..len {
3455 let c = *(octal_str + i as u64);
3456 if c >= '0' as u8 && c <= '7' as u8 {
3457 result = result * 8 + (c - '0' as u8) as u64;
3458 } else {
3459 break;
3460 }
3461 }
3462 return result;
3463 }
3464 fn tar_extract_initramfs(ramfs_base: u64, ramfs_size: u64) {
3465 let mut current_offset: u64 = 0;
3466 while current_offset < ramfs_size {
3467 let header = (ramfs_base + current_offset) as ptr<TarHeader>;
3468 if (*header).filename[0] == 0 { break; }
3469
3470 let size_val = tar_octal_to_int(&((*header).filesize[0]) as ptr<u8>, 11);
3471 let mode_val = tar_octal_to_int(&((*header).filemode[0]) as ptr<u8>, 7);
3472 let mut name_buf: [u8; 256];
3473 memset(&name_buf[0] as ptr<u8>, 0, 256);
3474
3475 if (*header).prefix[0] != 0 {
3476 strcpy(&name_buf[0] as ptr<u8>, &((*header).prefix[0]) as ptr<u8>);
3477 strcat(&name_buf[0] as ptr<u8>, "/" as ptr<u8>);
3478 }
3479 strcat(&name_buf[0] as ptr<u8>, &((*header).filename[0]) as ptr<u8>);
3480
3481 let file_data_ptr = ramfs_base + current_offset + 512;
3482
3483 if (*header).type_flag == '0' as u8 || (*header).type_flag == 0 {
3484 let mut fd: FileDescriptor;
3485 let node = vfs_create_node(global_vfs_root, &name_buf[0] as ptr<u8>, 0x06);
3486 (*node).ptr = file_data_ptr;
3487 (*node).length = size_val;
3488 (*node).uid = 0;
3489 (*node).gid = 0;
3490 } else if (*header).type_flag == '5' as u8 {
3491 vfs_create_node(global_vfs_root, &name_buf[0] as ptr<u8>, 0x07);
3492 }
3493
3494 let aligned_size = (size_val + 511) & !511;
3495 current_offset = current_offset + 512 + aligned_size;
3496 }
3497 }
3498 const REG_TYPE_INT: u32 = 1;
3499 const REG_TYPE_STR: u32 = 2;
3500 const REG_TYPE_BIN: u32 = 3;
3501 struct RegistryNode {
3502 key_name: [u8; 64],
3503 val_type: u32,
3504 val_int: u64,
3505 val_str: [u8; 256],
3506 val_bin: ptr<u8>,
3507 bin_len: u64,
3508 parent: ptr<RegistryNode>,
3509 child: ptr<RegistryNode>,
3510 next: ptr<RegistryNode>,
3511 }
3512 let mut global_registry_root: ptr<RegistryNode>;
3513 fn registry_init() {
3514 global_registry_root = pmm_alloc_blocks(1) as ptr<RegistryNode>;
3515 memset(global_registry_root as ptr<u8>, 0, sizeof(RegistryNode) as u64);
3516 strcpy(&((*global_registry_root).key_name[0]) as ptr<u8>, "ROOT" as ptr<u8>);
3517 }
3518 fn registry_create_key(parent: ptr<RegistryNode>, name: ptr<u8>) -> ptr<RegistryNode> {
3519 let node = pmm_alloc_blocks(1) as ptr<RegistryNode>;
3520 memset(node as ptr<u8>, 0, sizeof(RegistryNode) as u64);
3521 strcpy(&((*node).key_name[0]) as ptr<u8>, name);
3522 (*node).parent = parent;
3523
3524 if (*parent).child == 0 as ptr<RegistryNode> {
3525 (*parent).child = node;
3526 } else {
3527 let mut curr = (*parent).child;
3528 while (*curr).next != 0 as ptr<RegistryNode> {
3529 curr = (*curr).next;
3530 }
3531 (*curr).next = node;
3532 }
3533 return node;
3534 }
3535 fn registry_find_key(parent: ptr<RegistryNode>, name: ptr<u8>) -> ptr<RegistryNode> {
3536 let mut curr = (*parent).child;
3537 while curr != 0 as ptr<RegistryNode> {
3538 if strcmp(&((*curr).key_name[0]) as ptr<u8>, name) == 0 {
3539 return curr;
3540 }
3541 curr = (*curr).next;
3542 }
3543 return 0 as ptr<RegistryNode>;
3544 }
3545 fn registry_set_int(node: ptr<RegistryNode>, val: u64) {
3546 (*node).val_type = REG_TYPE_INT;
3547 (*node).val_int = val;
3548 }
3549 fn registry_set_str(node: ptr<RegistryNode>, val: ptr<u8>) {
3550 (*node).val_type = REG_TYPE_STR;
3551 strcpy(&((*node).val_str[0]) as ptr<u8>, val);
3552 }
3553 fn registry_set_bin(node: ptr<RegistryNode>, val: ptr<u8>, len: u64) {
3554 (*node).val_type = REG_TYPE_BIN;
3555 if (*node).val_bin != 0 as ptr<u8> {
3556 pmm_free_blocks((*node).val_bin as u64, ((*node).bin_len / PAGE_SIZE) + 1);
3557 }
3558 (*node).val_bin = pmm_alloc_blocks((len / PAGE_SIZE) + 1) as ptr<u8>;
3559 memcpy((*node).val_bin, val, len);
3560 (*node).bin_len = len;
3561 }
3562 struct UserAccount {
3563 uid: u32,
3564 gid: u32,
3565 username: [u8; 32],
3566 pass_hash: [u8; 32],
3567 pass_salt: [u8; 16],
3568 home_dir: [u8; 64],
3569 shell_path: [u8; 64],
3570 next: ptr<UserAccount>,
3571 }
3572 let mut global_user_db: ptr<UserAccount>;
3573 let mut next_uid: u32 = 1000;
3574 fn auth_init_system() {
3575 global_user_db = 0 as ptr<UserAccount>;
3576 let mut root_salt: [u8; 16];
3577 for i in 0..16 { root_salt[i] = (rand_next() & 0xFF) as u8; }
3578 auth_create_user("root" as ptr<u8>, "aegis_admin" as ptr<u8>, 0, 0, "/root" as ptr<u8>, "/bin/shell" as ptr<u8>);
3579 }
3580 fn auth_generate_hash(password: ptr<u8>, salt: ptr<u8>, out_hash: ptr<u8>) {
3581 let mut pass_len = strlen(password);
3582 let mut buffer: [u8; 128];
3583 memset(&buffer[0] as ptr<u8>, 0, 128);
3584 memcpy(&buffer[0] as ptr<u8>, password, pass_len);
3585 memcpy((&buffer[0] as u64 + pass_len) as ptr<u8>, salt, 16);
3586
3587 let mut ctx: Sha256Ctx;
3588 sha256_init(&ctx);
3589 sha256_transform(&ctx, &buffer[0] as ptr<u8>);
3590
3591 for iter in 0..999 {
3592 let mut temp_ctx: Sha256Ctx;
3593 sha256_init(&temp_ctx);
3594 let state_ptr = &ctx.state[0] as ptr<u32> as ptr<u8>;
3595 sha256_transform(&temp_ctx, state_ptr);
3596 for i in 0..8 { ctx.state[i] = temp_ctx.state[i]; }
3597 }
3598
3599 let state_ptr = &ctx.state[0] as ptr<u32> as ptr<u8>;
3600 for i in 0..32 {
3601 *(out_hash + i) = *(state_ptr + i);
3602 }
3603 }
3604 fn auth_create_user(username: ptr<u8>, password: ptr<u8>, uid_force: u32, gid: u32, home: ptr<u8>, shell: ptr<u8>) -> ptr<UserAccount> {
3605 let new_user = pmm_alloc_blocks(1) as ptr<UserAccount>;
3606 memset(new_user as ptr<u8>, 0, sizeof(UserAccount) as u64);
3607
3608 strcpy(&((*new_user).username[0]) as ptr<u8>, username);
3609 strcpy(&((*new_user).home_dir[0]) as ptr<u8>, home);
3610 strcpy(&((*new_user).shell_path[0]) as ptr<u8>, shell);
3611
3612 if uid_force != 0xFFFFFFFF {
3613 (*new_user).uid = uid_force;
3614 } else {
3615 (*new_user).uid = next_uid;
3616 next_uid = next_uid + 1;
3617 }
3618 (*new_user).gid = gid;
3619
3620 for i in 0..16 { (*new_user).pass_salt[i] = (rand_next() & 0xFF) as u8; }
3621 auth_generate_hash(password, &((*new_user).pass_salt[0]) as ptr<u8>, &((*new_user).pass_hash[0]) as ptr<u8>);
3622
3623 (*new_user).next = global_user_db;
3624 global_user_db = new_user;
3625 return new_user;
3626 }
3627 fn auth_verify_login(username: ptr<u8>, password: ptr<u8>) -> ptr<UserAccount> {
3628 let mut curr = global_user_db;
3629 while curr != 0 as ptr<UserAccount> {
3630 if strcmp(&((*curr).username[0]) as ptr<u8>, username) == 0 {
3631 let mut test_hash: [u8; 32];
3632 auth_generate_hash(password, &((*curr).pass_salt[0]) as ptr<u8>, &test_hash[0] as ptr<u8>);
3633 if memcmp(&((*curr).pass_hash[0]) as ptr<u8>, &test_hash[0] as ptr<u8>, 32) == 0 {
3634 return curr;
3635 } else {
3636 return 0 as ptr<UserAccount>;
3637 }
3638 }
3639 curr = (*curr).next;
3640 }
3641 return 0 as ptr<UserAccount>;
3642 }
3643 struct ServiceDaemon {
3644 name: [u8; 64],
3645 exec_path: [u8; 128],
3646 pid: u64,
3647 status: u32,
3648 runlevel: u32,
3649 restart_count: u32,
3650 deps: [u64; 8],
3651 dep_count: u32,
3652 next: ptr<ServiceDaemon>,
3653 }
3654 const SRV_STATUS_STOPPED: u32 = 0;
3655 const SRV_STATUS_STARTING: u32 = 1;
3656 const SRV_STATUS_RUNNING: u32 = 2;
3657 const SRV_STATUS_FAILED: u32 = 3;
3658 let mut global_service_list: ptr<ServiceDaemon>;
3659 let mut init_current_runlevel: u32 = 0;
3660 fn init_register_service(name: ptr<u8>, path: ptr<u8>, runlevel: u32) -> ptr<ServiceDaemon> {
3661 let srv = pmm_alloc_blocks(1) as ptr<ServiceDaemon>;
3662 memset(srv as ptr<u8>, 0, sizeof(ServiceDaemon) as u64);
3663 strcpy(&((*srv).name[0]) as ptr<u8>, name);
3664 strcpy(&((*srv).exec_path[0]) as ptr<u8>, path);
3665 (*srv).status = SRV_STATUS_STOPPED;
3666 (*srv).runlevel = runlevel;
3667 (*srv).dep_count = 0;
3668
3669 (*srv).next = global_service_list;
3670 global_service_list = srv;
3671 return srv;
3672 }
3673 fn init_add_dependency(srv: ptr<ServiceDaemon>, target_name: ptr<u8>) {
3674 let mut curr = global_service_list;
3675 while curr != 0 as ptr<ServiceDaemon> {
3676 if strcmp(&((*curr).name[0]) as ptr<u8>, target_name) == 0 {
3677 if (*srv).dep_count < 8 {
3678 (*srv).deps[(*srv).dep_count as usize] = curr as u64;
3679 (*srv).dep_count = (*srv).dep_count + 1;
3680 }
3681 return;
3682 }
3683 curr = (*curr).next;
3684 }
3685 }
3686 fn init_start_service(srv: ptr<ServiceDaemon>) -> bool {
3687 if (*srv).status == SRV_STATUS_RUNNING { return true; }
3688
3689 for i in 0..(*srv).dep_count {
3690 let dep = (*srv).deps[i as usize] as ptr<ServiceDaemon>;
3691 if dep == (0 as ptr<ServiceDaemon>) {
3692 (*srv).status = SRV_STATUS_FAILED;
3693 return false;
3694 }
3695 if (*dep).status != SRV_STATUS_RUNNING {
3696 if !init_start_service(dep) {
3697 (*srv).status = SRV_STATUS_FAILED;
3698 return false;
3699 }
3700 }
3701 }
3702
3703 (*srv).status = SRV_STATUS_STARTING;
3704 let pid = execve_ring3(&((*srv).exec_path[0]) as ptr<u8>, 0, 0);
3705 if pid > 0 {
3706 (*srv).pid = pid;
3707 (*srv).status = SRV_STATUS_RUNNING;
3708 return true;
3709 } else {
3710 (*srv).status = SRV_STATUS_FAILED;
3711 return false;
3712 }
3713 }
3714
3715 fn init_set_runlevel(level: u32) {
3716 init_current_runlevel = level;
3717 let mut curr = global_service_list;
3718 while curr != (0 as ptr<ServiceDaemon>) {
3719 if (*curr).runlevel <= level && (*curr).status == SRV_STATUS_STOPPED {
3720 init_start_service(curr);
3721 } else if (*curr).runlevel > level && (*curr).status == SRV_STATUS_RUNNING {
3722 let mut proc = process_queue;
3723 while proc != (0 as ptr<ProcessControlBlock>) {
3724 if (*proc).pid == (*curr).pid {
3725 kill_process((*curr).pid, 15);
3726 (*proc).state = 0;
3727 (*curr).status = SRV_STATUS_STOPPED;
3728 (*curr).pid = 0;
3729 break;
3730 }
3731 proc = (*proc).next;
3732 }
3733 }
3734 curr = (*curr).next;
3735 }
3736 }
3737
3738 fn init_monitor_loop() {
3739 loop {
3740 let mut curr = global_service_list;
3741 while curr != (0 as ptr<ServiceDaemon>) {
3742 if (*curr).status == SRV_STATUS_RUNNING {
3743 let mut is_alive = false;
3744 let mut proc = process_queue;
3745 while proc != (0 as ptr<ProcessControlBlock>) {
3746 if (*proc).pid == (*curr).pid && (*proc).state == 1 {
3747 is_alive = true;
3748 break;
3749 }
3750 proc = (*proc).next;
3751 }
3752 if !is_alive {
3753 (*curr).status = SRV_STATUS_FAILED;
3754 (*curr).pid = 0;
3755 (*curr).restart_count = (*curr).restart_count + 1;
3756 if (*curr).restart_count < 5 {
3757 init_start_service(curr);
3758 }
3759 }
3760 }
3761 curr = (*curr).next;
3762 }
3763 yield_cpu();
3764 }
3765 }
3766
3767 struct Ext2Superblock {
3768 s_inodes_count: u32,
3769 s_blocks_count: u32,
3770 s_r_blocks_count: u32,
3771 s_free_blocks_count: u32,
3772 s_free_inodes_count: u32,
3773 s_first_data_block: u32,
3774 s_log_block_size: u32,
3775 s_log_frag_size: i32,
3776 s_blocks_per_group: u32,
3777 s_frags_per_group: u32,
3778 s_inodes_per_group: u32,
3779 s_mtime: u32,
3780 s_wtime: u32,
3781 s_mnt_count: u16,
3782 s_max_mnt_count: i16,
3783 s_magic: u16,
3784 s_state: u16,
3785 s_errors: u16,
3786 s_minor_rev_level: u16,
3787 s_lastcheck: u32,
3788 s_checkinterval: u32,
3789 s_creator_os: u32,
3790 s_rev_level: u32,
3791 s_def_resuid: u16,
3792 s_def_resgid: u16,
3793 s_first_ino: u32,
3794 s_inode_size: u16,
3795 s_block_group_nr: u16,
3796 s_feature_compat: u32,
3797 s_feature_incompat: u32,
3798 s_feature_ro_compat: u32,
3799 s_uuid: [u8; 16],
3800 s_volume_name: [u8; 16],
3801 s_last_mounted: [u8; 64],
3802 s_algo_bitmap: u32,
3803 }
3804
3805 struct Ext2BlockGroupDesc {
3806 bg_block_bitmap: u32,
3807 bg_inode_bitmap: u32,
3808 bg_inode_table: u32,
3809 bg_free_blocks_count: u16,
3810 bg_free_inodes_count: u16,
3811 bg_used_dirs_count: u16,
3812 bg_pad: u16,
3813 bg_reserved: [u32; 3],
3814 }
3815
3816 struct Ext2Inode {
3817 i_mode: u16,
3818 i_uid: u16,
3819 i_size: u32,
3820 i_atime: u32,
3821 i_ctime: u32,
3822 i_mtime: u32,
3823 i_dtime: u32,
3824 i_gid: u16,
3825 i_links_count: u16,
3826 i_blocks: u32,
3827 i_flags: u32,
3828 i_osd1: u32,
3829 i_block: [u32; 15],
3830 i_generation: u32,
3831 i_file_acl: u32,
3832 i_dir_acl: u32,
3833 i_faddr: u32,
3834 i_osd2: [u32; 3],
3835 }
3836
3837 struct Ext2DirEntry {
3838 inode: u32,
3839 rec_len: u16,
3840 name_len: u8,
3841 file_type: u8,
3842 }
3843
3844 let mut ext2_sb: ptr<Ext2Superblock>;
3845 let mut ext2_bgdt: ptr<Ext2BlockGroupDesc>;
3846 let mut ext2_block_size: u32 = 0;
3847 let mut ext2_inodes_per_group: u32 = 0;
3848 let mut ext2_inode_size: u32 = 0;
3849 let mut ext2_block_groups_count: u32 = 0;
3850 let mut ext2_partition_base: u64 = 0;
3851 let mut ext2_dev_node: ptr<VfsNode> = 0 as ptr<VfsNode>;
3852
3853 fn ext2_read_block(block_num: u32, buf: ptr<u8>) {
3854 if block_num == 0 || ext2_dev_node == (0 as ptr<VfsNode>) { return; }
3855 let offset = ext2_partition_base + (block_num as u64 * ext2_block_size as u64);
3856 let mut dev_fd: FileDescriptor;
3857 dev_fd.node = ext2_dev_node;
3858 dev_fd.offset = offset;
3859 vfs_read(&mut dev_fd as ptr<FileDescriptor>, buf, ext2_block_size as u64);
3860 }
3861
3862 fn ext2_init(partition_base: u64) -> bool {
3863 ext2_partition_base = partition_base;
3864 ext2_dev_node = vfs_find_child(global_vfs_root, "dev/sda1" as ptr<u8>);
3865 if ext2_dev_node == (0 as ptr<VfsNode>) { return false; }
3866
3867 let sb_buf = pmm_alloc_blocks(1) as ptr<u8>;
3868 let mut dev_fd: FileDescriptor;
3869 dev_fd.node = ext2_dev_node;
3870 dev_fd.offset = ext2_partition_base + 1024;
3871 vfs_read(&mut dev_fd as ptr<FileDescriptor>, sb_buf, 1024);
3872
3873 ext2_sb = sb_buf as ptr<Ext2Superblock>;
3874 if (*ext2_sb).s_magic != 0xEF53 {
3875 pmm_free_blocks(sb_buf as u64, 1);
3876 ext2_sb = 0 as ptr<Ext2Superblock>;
3877 return false;
3878 }
3879
3880 ext2_block_size = 1024 << (*ext2_sb).s_log_block_size;
3881 ext2_inodes_per_group = (*ext2_sb).s_inodes_per_group;
3882 if (*ext2_sb).s_rev_level == 0 {
3883 ext2_inode_size = 128;
3884 } else {
3885 ext2_inode_size = (*ext2_sb).s_inode_size as u32;
3886 }
3887
3888 let blocks_count = (*ext2_sb).s_blocks_count;
3889 let blocks_per_group = (*ext2_sb).s_blocks_per_group;
3890 ext2_block_groups_count = (blocks_count + blocks_per_group - 1) / blocks_per_group;
3891
3892 let bgdt_bytes = ext2_block_groups_count as u64 * sizeof(Ext2BlockGroupDesc) as u64;
3893 let bgdt_blocks = (bgdt_bytes + ext2_block_size as u64 - 1) / ext2_block_size as u64;
3894 let bgdt_mem_blocks = (bgdt_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
3895
3896 let bgdt_start_block = if ext2_block_size == 1024 { 2 } else { 1 };
3897 let bgdt_buf = pmm_alloc_blocks(bgdt_mem_blocks) as ptr<u8>;
3898
3899 for i in 0..bgdt_blocks {
3900 ext2_read_block(
3901 bgdt_start_block + i as u32,
3902 (bgdt_buf as u64 + i * ext2_block_size as u64) as ptr<u8>
3903 );
3904 }
3905 ext2_bgdt = bgdt_buf as ptr<Ext2BlockGroupDesc>;
3906 return true;
3907 }
3908
3909 fn ext2_get_inode(inode_num: u32, out_inode: ptr<Ext2Inode>) -> bool {
3910 if inode_num == 0 || ext2_inodes_per_group == 0 { return false; }
3911
3912 let bg_idx = (inode_num - 1) / ext2_inodes_per_group;
3913 let local_idx = (inode_num - 1) % ext2_inodes_per_group;
3914 if bg_idx >= ext2_block_groups_count { return false; }
3915
3916 let bgd = (ext2_bgdt as u64 + bg_idx as u64 * sizeof(Ext2BlockGroupDesc) as u64) as ptr<Ext2BlockGroupDesc>;
3917 let inode_table_block = (*bgd).bg_inode_table;
3918 let byte_offset = local_idx * ext2_inode_size;
3919 let block_offset = byte_offset / ext2_block_size;
3920 let internal_offset = byte_offset % ext2_block_size;
3921 let target_block = inode_table_block + block_offset;
3922
3923 let mem_blocks = (ext2_block_size as u64 + PAGE_SIZE - 1) / PAGE_SIZE;
3924 let buf = pmm_alloc_blocks(mem_blocks) as ptr<u8>;
3925 ext2_read_block(target_block, buf);
3926
3927 let copy_size = if (sizeof(Ext2Inode) as u32) < ext2_inode_size {
3928 sizeof(Ext2Inode) as u64
3929 } else {
3930 ext2_inode_size as u64
3931 };
3932
3933 memcpy(out_inode as ptr<u8>, (buf as u64 + internal_offset as u64) as ptr<u8>, copy_size);
3934 pmm_free_blocks(buf as u64, mem_blocks);
3935 return true;
3936 }
3937
3938 fn ext2_read_inode_data(inode: ptr<Ext2Inode>, buf: ptr<u8>) {
3939 if (*inode).i_size == 0 || ext2_block_size == 0 { return; }
3940
3941 let blocks_to_read = ((*inode).i_size + ext2_block_size - 1) / ext2_block_size;
3942 let mem_blocks = (ext2_block_size as u64 + PAGE_SIZE - 1) / PAGE_SIZE;
3943 let ptrs_per_block = ext2_block_size / 4;
3944
3945 let mut current_block: u32 = 0;
3946 while current_block < blocks_to_read && current_block < 12 {
3947 let physical_block = (*inode).i_block[current_block as usize];
3948 if physical_block != 0 {
3949 ext2_read_block(
3950 physical_block,
3951 (buf as u64 + current_block as u64 * ext2_block_size as u64) as ptr<u8>
3952 );
3953 } else {
3954 memset(
3955 (buf as u64 + current_block as u64 * ext2_block_size as u64) as ptr<u8>,
3956 0,
3957 ext2_block_size as u64
3958 );
3959 }
3960 current_block = current_block + 1;
3961 }
3962
3963 if current_block < blocks_to_read && (*inode).i_block[12] != 0 {
3964 let indirect_buf = pmm_alloc_blocks(mem_blocks) as ptr<u32>;
3965 ext2_read_block((*inode).i_block[12], indirect_buf as ptr<u8>);
3966
3967 let mut i: u32 = 0;
3968 while current_block < blocks_to_read && i < ptrs_per_block {
3969 let physical_block = *(indirect_buf as u64 + i as u64 * 4) as ptr<u32>;
3970 if *physical_block != 0 {
3971 ext2_read_block(
3972 *physical_block,
3973 (buf as u64 + current_block as u64 * ext2_block_size as u64) as ptr<u8>
3974 );
3975 } else {
3976 memset(
3977 (buf as u64 + current_block as u64 * ext2_block_size as u64) as ptr<u8>,
3978 0,
3979 ext2_block_size as u64
3980 );
3981 }
3982 current_block = current_block + 1;
3983 i = i + 1;
3984 }
3985 pmm_free_blocks(indirect_buf as u64, mem_blocks);
3986 }
3987 }
3988
3989 struct Elf64_Sym {
3990 st_name: u32,
3991 st_info: u8,
3992 st_other: u8,
3993 st_shndx: u16,
3994 st_value: u64,
3995 st_size: u64,
3996 }
3997
3998 struct Elf64_Rela {
3999 r_offset: u64,
4000 r_info: u64,
4001 r_addend: i64,
4002 }
4003
4004 struct Elf64_Dyn {
4005 d_tag: u64,
4006 d_val: u64,
4007 }
4008
4009 fn elf64_r_sym(info: u64) -> u32 {
4010 return (info >> 32) as u32;
4011 }
4012
4013 fn elf64_r_type(info: u64) -> u32 {
4014 return (info & 0xFFFFFFFF) as u32;
4015 }
4016
4017 fn elf64_apply_rela(base_load_addr: u64, rela_tab: ptr<Elf64_Rela>, count: u64, sym_tab: ptr<Elf64_Sym>) {
4018 let mut i: u64 = 0;
4019 while i < count {
4020 let rel = (rela_tab as u64 + i * sizeof(Elf64_Rela) as u64) as ptr<Elf64_Rela>;
4021 let target = (base_load_addr + (*rel).r_offset) as ptr<u64>;
4022 let rel_type = elf64_r_type((*rel).r_info);
4023 let sym_idx = elf64_r_sym((*rel).r_info);
4024
4025 if rel_type == 8 {
4026 *target = (base_load_addr as i64 + (*rel).r_addend) as u64;
4027 } else if rel_type == 6 || rel_type == 7 || rel_type == 1 {
4028 let sym = (sym_tab as u64 + sym_idx as u64 * sizeof(Elf64_Sym) as u64) as ptr<Elf64_Sym>;
4029 let sym_val = if (*sym).st_shndx != 0 {
4030 base_load_addr + (*sym).st_value
4031 } else {
4032 0
4033 };
4034 if rel_type == 6 || rel_type == 7 {
4035 *target = (sym_val as i64 + (*rel).r_addend) as u64;
4036 } else if rel_type == 1 {
4037 *target = (sym_val as i64 + (*rel).r_addend) as u64;
4038 }
4039 }
4040 i = i + 1;
4041 }
4042 }
4043 const DT_NULL: u64 = 0;
4044 const DT_NEEDED: u64 = 1;
4045 const DT_PLTRELSZ: u64 = 2;
4046 const DT_PLTGOT: u64 = 3;
4047 const DT_HASH: u64 = 4;
4048 const DT_STRTAB: u64 = 5;
4049 const DT_SYMTAB: u64 = 6;
4050 const DT_RELA: u64 = 7;
4051 const DT_RELASZ: u64 = 8;
4052 const DT_RELAENT: u64 = 9;
4053 const DT_STRSZ: u64 = 10;
4054 const DT_SYMENT: u64 = 11;
4055 const R_X86_64_NONE: u64 = 0;
4056 const R_X86_64_64: u64 = 1;
4057 const R_X86_64_PC32: u64 = 2;
4058 const R_X86_64_GOT32: u64 = 3;
4059 const R_X86_64_PLT32: u64 = 4;
4060 const R_X86_64_COPY: u64 = 5;
4061 const R_X86_64_GLOB_DAT: u64 = 6;
4062 const R_X86_64_JUMP_SLOT: u64 = 7;
4063 const R_X86_64_RELATIVE: u64 = 8;
4064 fn elf_resolve_dynamic(load_base: u64, dyn_table: ptr<Elf64_Dyn>) {
4065 let mut strtab: ptr<u8> = 0 as ptr<u8>;
4066 let mut symtab: ptr<Elf64_Sym> = 0 as ptr<Elf64_Sym>;
4067 let mut rela: ptr<Elf64_Rela> = 0 as ptr<Elf64_Rela>;
4068 let mut relasz: u64 = 0;
4069
4070 let mut curr = dyn_table;
4071 while (*curr).d_tag != DT_NULL {
4072 if (*curr).d_tag == DT_STRTAB { strtab = (load_base + (*curr).d_val) as ptr<u8>; }
4073 else if (*curr).d_tag == DT_SYMTAB { symtab = (load_base + (*curr).d_val) as ptr<Elf64_Sym>; }
4074 else if (*curr).d_tag == DT_RELA { rela = (load_base + (*curr).d_val) as ptr<Elf64_Rela>; }
4075 else if (*curr).d_tag == DT_RELASZ { relasz = (*curr).d_val; }
4076 curr = (curr as u64 + sizeof(Elf64_Dyn) as u64) as ptr<Elf64_Dyn>;
4077 }
4078
4079 if rela != 0 as ptr<Elf64_Rela> && symtab != 0 as ptr<Elf64_Sym> {
4080 let rela_count = relasz / sizeof(Elf64_Rela) as u64;
4081 for i in 0..rela_count {
4082 let rel = (rela as u64 + i * sizeof(Elf64_Rela) as u64) as ptr<Elf64_Rela>;
4083 let r_type = (*rel).r_info & 0xFFFFFFFF;
4084 let sym_idx = (*rel).r_info >> 32;
4085 let target_addr = (load_base + (*rel).r_offset) as ptr<u64>;
4086
4087 if r_type == R_X86_64_RELATIVE {
4088 *target_addr = (load_base as i64 + (*rel).r_addend) as u64;
4089 } else if r_type == R_X86_64_GLOB_DAT || r_type == R_X86_64_JUMP_SLOT || r_type == R_X86_64_64 {
4090 let sym = (symtab as u64 + sym_idx * sizeof(Elf64_Sym) as u64) as ptr<Elf64_Sym>;
4091 let sym_val = (*sym).st_value;
4092 if sym_val != 0 {
4093 *target_addr = (load_base + sym_val) as i64 as u64 + (*rel).r_addend as u64;
4094 }
4095 }
4096 }
4097 }
4098 }
4099 struct AnsiState {
4100 in_escape: bool,
4101 in_bracket: bool,
4102 params: [u32; 8],
4103 param_count: u32,
4104 current_param: u32,
4105 saved_x: u32,
4106 saved_y: u32,
4107 }
4108 let mut global_ansi_state: AnsiState;
4109 fn ansi_init() {
4110 global_ansi_state.in_escape = false;
4111 global_ansi_state.in_bracket = false;
4112 global_ansi_state.param_count = 0;
4113 global_ansi_state.current_param = 0;
4114 global_ansi_state.saved_x = 0;
4115 global_ansi_state.saved_y = 0;
4116 }
4117 fn ansi_apply_colors() {
4118 for i in 0..global_ansi_state.param_count {
4119 let p = global_ansi_state.params[i as usize];
4120 if p == 0 {
4121 (*global_shell).fg_color = 0xFFFFFF;
4122 } else if p >= 30 && p <= 37 {
4123 if p == 30 { (*global_shell).fg_color = 0x000000; }
4124 else if p == 31 { (*global_shell).fg_color = 0xFF0000; }
4125 else if p == 32 { (*global_shell).fg_color = 0x00FF00; }
4126 else if p == 33 { (*global_shell).fg_color = 0xFFFF00; }
4127 else if p == 34 { (*global_shell).fg_color = 0x0000FF; }
4128 else if p == 35 { (*global_shell).fg_color = 0xFF00FF; }
4129 else if p == 36 { (*global_shell).fg_color = 0x00FFFF; }
4130 else if p == 37 { (*global_shell).fg_color = 0xFFFFFF; }
4131 }
4132 }
4133 }
4134 fn ansi_process_char(c: u8) -> bool {
4135 if c == 27 {
4136 global_ansi_state.in_escape = true;
4137 global_ansi_state.in_bracket = false;
4138 global_ansi_state.param_count = 0;
4139 global_ansi_state.current_param = 0;
4140 return true;
4141 }
4142 if global_ansi_state.in_escape {
4143 if !global_ansi_state.in_bracket {
4144 if c == '[' as u8 {
4145 global_ansi_state.in_bracket = true;
4146 } else {
4147 global_ansi_state.in_escape = false;
4148 }
4149 return true;
4150 }
4151
4152 if c >= '0' as u8 && c <= '9' as u8 {
4153 global_ansi_state.current_param = global_ansi_state.current_param * 10 + (c - '0' as u8) as u32;
4154 return true;
4155 } else if c == ';' as u8 {
4156 if global_ansi_state.param_count < 8 {
4157 global_ansi_state.params[global_ansi_state.param_count as usize] = global_ansi_state.current_param;
4158 global_ansi_state.param_count = global_ansi_state.param_count + 1;
4159 }
4160 global_ansi_state.current_param = 0;
4161 return true;
4162 } else {
4163 if global_ansi_state.param_count < 8 {
4164 global_ansi_state.params[global_ansi_state.param_count as usize] = global_ansi_state.current_param;
4165 global_ansi_state.param_count = global_ansi_state.param_count + 1;
4166 }
4167
4168 if c == 'm' as u8 {
4169 ansi_apply_colors();
4170 } else if c == 'H' as u8 || c == 'f' as u8 {
4171 let row = if global_ansi_state.param_count > 0 { global_ansi_state.params[0] } else { 1 };
4172 let col = if global_ansi_state.param_count > 1 { global_ansi_state.params[1] } else { 1 };
4173 (*global_shell).cx = col * system_font_w;
4174 (*global_shell).cy = row * system_font_h;
4175 } else if c == 'J' as u8 {
4176 if global_ansi_state.params[0] == 2 {
4177 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
4178 (*global_shell).cx = 2; (*global_shell).cy = 2;
4179 }
4180 }
4181
4182 global_ansi_state.in_escape = false;
4183 return true;
4184 }
4185 }
4186 return false;
4187 }
4188 struct ShmSegment {
4189 shm_id: u64,
4190 key: u32,
4191 size: u64,
4192 phys_base: u64,
4193 ref_count: u32,
4194 owner_pid: u64,
4195 permissions: u32,
4196 }
4197 let mut global_shm_table: [ShmSegment; 256];
4198 let mut shm_next_id: u64 = 100;
4199 let mut shm_lock: Spinlock;
4200 fn shm_init() {
4201 spin_init(&shm_lock);
4202 for i in 0..256 {
4203 global_shm_table[i].shm_id = 0;
4204 }
4205 }
4206 fn shm_create(key: u32, size: u64, permissions: u32, pid: u64) -> u64 {
4207 spin_lock(&shm_lock);
4208 for i in 0..256 {
4209 if global_shm_table[i].key == key && global_shm_table[i].shm_id != 0 {
4210 spin_unlock(&shm_lock);
4211 return global_shm_table[i].shm_id;
4212 }
4213 }
4214
4215 for i in 0..256 {
4216 if global_shm_table[i].shm_id == 0 {
4217 let pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
4218 let phys = pmm_alloc_blocks(pages);
4219 memset(phys as ptr<u8>, 0, pages * PAGE_SIZE);
4220
4221 global_shm_table[i].shm_id = shm_next_id;
4222 shm_next_id = shm_next_id + 1;
4223 global_shm_table[i].key = key;
4224 global_shm_table[i].size = size;
4225 global_shm_table[i].phys_base = phys;
4226 global_shm_table[i].ref_count = 0;
4227 global_shm_table[i].owner_pid = pid;
4228 global_shm_table[i].permissions = permissions;
4229
4230 spin_unlock(&shm_lock);
4231 return global_shm_table[i].shm_id;
4232 }
4233 }
4234 spin_unlock(&shm_lock);
4235 return 0;
4236 }
4237 fn shm_attach(shm_id: u64, cr3: u64, vaddr_suggest: u64) -> u64 {
4238 spin_lock(&shm_lock);
4239 for i in 0..256 {
4240 if global_shm_table[i].shm_id == shm_id {
4241 let pages = (global_shm_table[i].size + PAGE_SIZE - 1) / PAGE_SIZE;
4242 let mut vaddr = vaddr_suggest;
4243 if vaddr == 0 { vaddr = 0x5000000000; }
4244
4245 let old_cr3 = rdmsr(0);
4246 asm { "mov cr3, %0" in "%0" = cr3; }
4247 for p in 0..pages {
4248 vmm_map_page(global_shm_table[i].phys_base + p * PAGE_SIZE, vaddr + p * PAGE_SIZE, 0x07);
4249 }
4250 asm { "mov cr3, %0" in "%0" = old_cr3; }
4251
4252 global_shm_table[i].ref_count = global_shm_table[i].ref_count + 1;
4253 spin_unlock(&shm_lock);
4254 return vaddr;
4255 }
4256 }
4257 spin_unlock(&shm_lock);
4258 return 0;
4259 }
4260 struct ProcessStat {
4261 pid: u64,
4262 state: u8,
4263 time_slice: u64,
4264 vram_usage: u64,
4265 name: [u8; 32],
4266 }
4267 fn get_system_stats(out_stats: ptr<ProcessStat>, max_count: u32) -> u32 {
4268 let mut count = 0;
4269 let mut curr = process_queue;
4270 while curr != 0 as ptr<ProcessControlBlock> && count < max_count {
4271 let stat = (out_stats as u64 + count as u64 * sizeof(ProcessStat) as u64) as ptr<ProcessStat>;
4272 (*stat).pid = (*curr).pid;
4273 (*stat).state = (*curr).state;
4274 (*stat).time_slice = (*curr).time_slice;
4275 (*stat).vram_usage = 0;
4276 count = count + 1;
4277 curr = (*curr).next;
4278 }
4279 return count;
4280 }
4281 let mut loopback_mac: MacAddr;
4282 let mut loopback_ip: Ipv4Addr;
4283 fn loopback_init() {
4284 for i in 0..6 { loopback_mac.addr[i] = 0; }
4285 loopback_ip.addr[0] = 127;
4286 loopback_ip.addr[1] = 0;
4287 loopback_ip.addr[2] = 0;
4288 loopback_ip.addr[3] = 1;
4289 }
4290 fn loopback_send(packet: ptr<u8>, length: u32) {
4291 let rx_buffer = pmm_alloc_blocks((length as u64 / PAGE_SIZE) + 1) as ptr<u8>;
4292 memcpy(rx_buffer, packet, length as u64);
4293 pmm_free_blocks(rx_buffer as u64, (length as u64 / PAGE_SIZE) + 1);
4294 }
4295 struct AegisContainer {
4296 container_id: u64,
4297 vfs_root: ptr<VfsNode>,
4298 pid_offset: u64,
4299 network_isolated: bool,
4300 virtual_ip: Ipv4Addr,
4301 memory_limit: u64,
4302 current_memory: u64,
4303 is_active: bool,
4304 name: [u8; 32],
4305 }
4306 let mut global_containers: [AegisContainer; 64];
4307 let mut container_count: u64 = 1;
4308 fn container_init() {
4309 for i in 0..64 {
4310 global_containers[i].is_active = false;
4311 }
4312 }
4313 fn container_create(name: ptr<u8>, mem_limit: u64) -> ptr<AegisContainer> {
4314 for i in 0..64 {
4315 if !global_containers[i].is_active {
4316 global_containers[i].container_id = container_count;
4317 container_count = container_count + 1;
4318 strcpy(&(global_containers[i].name[0]) as ptr<u8>, name);
4319 global_containers[i].memory_limit = mem_limit;
4320 global_containers[i].current_memory = 0;
4321 global_containers[i].pid_offset = container_count * 10000;
4322 global_containers[i].network_isolated = true;
4323
4324 let root_name = pmm_alloc_blocks(1) as ptr<u8>;
4325 strcpy(root_name, "c_root" as ptr<u8>);
4326 global_containers[i].vfs_root = vfs_create_node(global_vfs_root, root_name, 0x07);
4327 pmm_free_blocks(root_name as u64, 1);
4328
4329 global_containers[i].is_active = true;
4330 return &global_containers[i];
4331 }
4332 }
4333 return 0 as ptr<AegisContainer>;
4334 }
4335 fn container_execute(container: ptr<AegisContainer>, path: ptr<u8>) -> u64 {
4336 let node = vfs_find_child((*container).vfs_root, path);
4337 if node == 0 as ptr<VfsNode> { return 0; }
4338
4339 let pid = execve_ring3(path, 0, 0);
4340 if pid != 0 {
4341 let mut proc = process_queue;
4342 while proc != 0 as ptr<ProcessControlBlock> {
4343 if (*proc).pid == pid {
4344 (*proc).pid = (*container).pid_offset + pid;
4345 break;
4346 }
4347 proc = (*proc).next;
4348 }
4349 return (*container).pid_offset + pid;
4350 }
4351 return 0;
4352 }
4353 struct IntelGpuRing {
4354 tail: u32,
4355 head: u32,
4356 start: u32,
4357 ctl: u32,
4358 }
4359 let mut intel_mmio_base: u64 = 0;
4360 let mut intel_ring_buf: ptr<u32>;
4361 let mut intel_ring_tail: u32 = 0;
4362 fn intel_gpu_read(offset: u32) -> u32 {
4363 let ptr = (intel_mmio_base + offset as u64) as ptr<u32>;
4364 return *ptr;
4365 }
4366 fn intel_gpu_write(offset: u32, val: u32) {
4367 let ptr = (intel_mmio_base + offset as u64) as ptr<u32>;
4368 *ptr = val;
4369 }
4370 fn intel_gpu_init(bar0: u64) {
4371 intel_mmio_base = bar0 & 0xFFFFFFFFFFFFFFF0;
4372 intel_ring_buf = pmm_alloc_blocks(4) as ptr<u32>;
4373 memset(intel_ring_buf as ptr<u8>, 0, PAGE_SIZE * 4);
4374
4375 intel_gpu_write(0x02080, 0);
4376 intel_gpu_write(0x02030, 0);
4377 intel_gpu_write(0x02034, intel_ring_buf as u64 as u32);
4378 let ring_size = (PAGE_SIZE * 4) as u32;
4379 intel_gpu_write(0x02038, ((ring_size / 4096) - 1) | 1);
4380
4381 intel_ring_tail = 0;
4382 }
4383 fn intel_gpu_submit_cmd(cmd: u32) {
4384 *(intel_ring_buf as u64 + intel_ring_tail as u64 * 4) as ptr<u32> = cmd;
4385 intel_ring_tail = (intel_ring_tail + 1) % ((PAGE_SIZE as u32 * 4) / 4);
4386 let aligned_tail = (intel_ring_tail * 4) & 0x1FFFF8;
4387 intel_gpu_write(0x02030, aligned_tail);
4388 }
4389 fn intel_gpu_fill_rect(x: u32, y: u32, w: u32, h: u32, color: u32) {
4390 let cmd_len = 6;
4391 intel_gpu_submit_cmd(0x50000000 | (cmd_len - 2));
4392 intel_gpu_submit_cmd((y << 16) | x);
4393 intel_gpu_submit_cmd(((y + h) << 16) | (x + w));
4394 intel_gpu_submit_cmd(color);
4395 intel_gpu_submit_cmd(0);
4396 intel_gpu_submit_cmd(0);
4397 }
4398 const PCI_CAP_ID_MSI: u8 = 0x05;
4399 const PCI_CAP_ID_MSIX: u8 = 0x11;
4400 struct MsixTableEntry {
4401 msg_addr_lo: u32,
4402 msg_addr_hi: u32,
4403 msg_data: u32,
4404 vector_ctrl: u32,
4405 }
4406 fn pcie_find_capability(base: u64, bus: u8, dev: u8, func: u8, cap_id: u8) -> u8 {
4407 let status = pcie_read_16(base, bus, dev, func, 0x06);
4408 if (status & 0x0010) == 0 { return 0; }
4409
4410 let mut cap_ptr = pcie_read_16(base, bus, dev, func, 0x34) & 0xFC;
4411 while cap_ptr != 0 {
4412 let cap_data = pcie_read_16(base, bus, dev, func, cap_ptr);
4413 let id = (cap_data & 0xFF) as u8;
4414 let next = ((cap_data >> 8) & 0xFC) as u8;
4415 if id == cap_id { return cap_ptr as u8; }
4416 cap_ptr = next as u16;
4417 }
4418 return 0;
4419 }
4420 fn pcie_enable_msix(base: u64, bus: u8, dev: u8, func: u8, vector: u8, apic_id: u8) {
4421 let cap_offset = pcie_find_capability(base, bus, dev, func, PCI_CAP_ID_MSIX);
4422 if cap_offset == 0 { return; }
4423
4424 let msg_ctrl = pcie_read_16(base, bus, dev, func, cap_offset as u16 + 2);
4425 let table_offset_reg = pcie_read_32(base, bus, dev, func, cap_offset as u16 + 4);
4426 let bir = (table_offset_reg & 0x07) as u8;
4427 let table_offset = table_offset_reg & 0xFFFFFFF8;
4428
4429 let bar_reg = 0x10 + (bir * 4);
4430 let bar_val = pcie_read_32(base, bus, dev, func, bar_reg as u16);
4431 let bar_base = (bar_val & 0xFFFFFFF0) as u64;
4432
4433 let table_ptr = (bar_base + table_offset as u64) as ptr<MsixTableEntry>;
4434
4435 let addr_lo = 0xFEE00000 | ((apic_id as u32) << 12);
4436 let data = vector as u32;
4437
4438 (*table_ptr).msg_addr_lo = addr_lo;
4439 (*table_ptr).msg_addr_hi = 0;
4440 (*table_ptr).msg_data = data;
4441 (*table_ptr).vector_ctrl = 0;
4442
4443 pcie_write_32(base, bus, dev, func, cap_offset as u16 + 2, (msg_ctrl | 0x8000) as u32);
4444 }
4445 struct RiffHeader {
4446 chunk_id: u32,
4447 chunk_size: u32,
4448 format: u32,
4449 }
4450 struct WavFormatChunk {
4451 subchunk1_id: u32,
4452 subchunk1_size: u32,
4453 audio_format: u16,
4454 num_channels: u16,
4455 sample_rate: u32,
4456 byte_rate: u32,
4457 block_align: u16,
4458 bits_per_sample: u16,
4459 }
4460 struct WavDataChunk {
4461 subchunk2_id: u32,
4462 subchunk2_size: u32,
4463 }
4464 fn audio_play_wav(wav_data: ptr<u8>) {
4465 let riff = wav_data as ptr<RiffHeader>;
4466 if (*riff).chunk_id != 0x46464952 { return; } // 'RIFF'
4467 if (*riff).format != 0x45564157 { return; } // 'WAVE'
4468
4469 let fmt = (wav_data as u64 + sizeof(RiffHeader) as u64) as ptr<WavFormatChunk>;
4470 if (*fmt).subchunk1_id != 0x20746d66 { return; } // 'fmt '
4471
4472 let data_offset = sizeof(RiffHeader) as u64 + 8 + (*fmt).subchunk1_size as u64;
4473 let data_chunk = (wav_data as u64 + data_offset) as ptr<WavDataChunk>;
4474 if (*data_chunk).subchunk2_id != 0x61746164 { return; } // 'data'
4475
4476 let pcm_data = (wav_data as u64 + data_offset + 8) as ptr<u8>;
4477 let pcm_size = (*data_chunk).subchunk2_size;
4478
4479 mixer_play_pcm(pcm_data, pcm_size / 4, (*fmt).sample_rate);
4480 }
4481 struct NatEntry {
4482 internal_ip: Ipv4Addr,
4483 internal_port: u16,
4484 external_port: u16,
4485 protocol: u8,
4486 is_active: bool,
4487 }
4488 let mut global_nat_table: [NatEntry; 1024];
4489 let mut nat_next_port: u16 = 50000;
4490 fn nat_init() {
4491 for i in 0..1024 {
4492 global_nat_table[i].is_active = false;
4493 }
4494 }
4495 fn nat_add_mapping(int_ip: Ipv4Addr, int_port: u16, proto: u8) -> u16 {
4496 for i in 0..1024 {
4497 if !global_nat_table[i].is_active {
4498 global_nat_table[i].internal_ip = int_ip;
4499 global_nat_table[i].internal_port = int_port;
4500 global_nat_table[i].external_port = nat_next_port;
4501 global_nat_table[i].protocol = proto;
4502 global_nat_table[i].is_active = true;
4503
4504 let port = nat_next_port;
4505 nat_next_port = nat_next_port + 1;
4506 if nat_next_port > 65000 { nat_next_port = 50000; }
4507 return port;
4508 }
4509 }
4510 return 0;
4511 }
4512 fn nat_translate_outbound(packet: ptr<u8>) {
4513 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
4514 let proto = (*iph).protocol;
4515
4516 if proto == 6 {
4517 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
4518 let ext_port = nat_add_mapping((*iph).src_ip, htons((*tcph).src_port), proto);
4519
4520 for i in 0..4 { (*iph).src_ip.addr[i] = system_ip.addr[i]; }
4521 (*tcph).src_port = htons(ext_port);
4522 (*tcph).checksum = 0;
4523 (*iph).checksum = 0;
4524 }
4525 }
4526 fn nat_translate_inbound(packet: ptr<u8>) -> bool {
4527 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
4528 let proto = (*iph).protocol;
4529
4530 if proto == 6 {
4531 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
4532 let dest_port = htons((*tcph).dest_port);
4533
4534 for i in 0..1024 {
4535 if global_nat_table[i].is_active && global_nat_table[i].external_port == dest_port && global_nat_table[i].protocol == proto {
4536 for j in 0..4 { (*iph).dest_ip.addr[j] = global_nat_table[i].internal_ip.addr[j]; }
4537 (*tcph).dest_port = htons(global_nat_table[i].internal_port);
4538 return true;
4539 }
4540 }
4541 }
4542 return false;
4543 }
4544 struct AhciCmdFis {
4545 fis_type: u8,
4546 pmport_c: u8,
4547 command: u8,
4548 feature_l: u8,
4549 lba0: u8,
4550 lba1: u8,
4551 lba2: u8,
4552 device: u8,
4553 lba3: u8,
4554 lba4: u8,
4555 lba5: u8,
4556 feature_h: u8,
4557 count_l: u8,
4558 count_h: u8,
4559 icc: u8,
4560 control: u8,
4561 rsv1: [u8; 4],
4562 }
4563 fn ahci_find_cmd_slot(port: ptr<AHCIPortRegs>) -> i32 {
4564 let slots = ((*global_ahci_hba).cap >> 8) & 0x1F;
4565 for i in 0..=slots {
4566 if ((*port).ci & (1 << i)) == 0 && ((*port).sact & (1 << i)) == 0 {
4567 return i as i32;
4568 }
4569 }
4570 return -1;
4571 }
4572 fn ahci_read_sectors(port: ptr<AHCIPortRegs>, start_lba: u64, count: u32, buf_phys: u64) -> bool {
4573 (*port).is = 0xFFFFFFFF;
4574 let slot = ahci_find_cmd_slot(port);
4575 if slot == -1 { return false; }
4576
4577 let cmd_header = ((*port).clb + (slot as u64 * sizeof(AHCICmdHeader) as u64)) as ptr<AHCICmdHeader>;
4578 (*cmd_header).cfl_p_r_c = (sizeof(AhciCmdFis) / 4) as u16;
4579 (*cmd_header).prdtl = 1;
4580
4581 let cmd_table = (*cmd_header).ctba as ptr<AHCICmdTable>;
4582 memset(cmd_table as ptr<u8>, 0, sizeof(AHCICmdTable) as u64);
4583
4584 (*cmd_table).prdt_entry[0].dba = buf_phys;
4585 (*cmd_table).prdt_entry[0].dbc_i = (count * 512) - 1;
4586
4587 let fis = &(*cmd_table).cfis[0] as ptr<AhciCmdFis>;
4588 (*fis).fis_type = 0x27;
4589 (*fis).pmport_c = 0x80;
4590 (*fis).command = 0x25;
4591
4592 (*fis).lba0 = (start_lba & 0xFF) as u8;
4593 (*fis).lba1 = ((start_lba >> 8) & 0xFF) as u8;
4594 (*fis).lba2 = ((start_lba >> 16) & 0xFF) as u8;
4595 (*fis).device = 0x40;
4596
4597 (*fis).lba3 = ((start_lba >> 24) & 0xFF) as u8;
4598 (*fis).lba4 = ((start_lba >> 32) & 0xFF) as u8;
4599 (*fis).lba5 = ((start_lba >> 40) & 0xFF) as u8;
4600
4601 (*fis).count_l = (count & 0xFF) as u8;
4602 (*fis).count_h = ((count >> 8) & 0xFF) as u8;
4603
4604 while ((*port).tfd & (0x80 | 0x08)) != 0 { cpu_pause(); }
4605 (*port).ci = 1 << slot;
4606
4607 while true {
4608 if ((*port).ci & (1 << slot)) == 0 { break; }
4609 if ((*port).is & 0x40000000) != 0 { return false; }
4610 cpu_pause();
4611 }
4612 return true;
4613 }
4614 fn ahci_write_sectors(port: ptr<AHCIPortRegs>, start_lba: u64, count: u32, buf_phys: u64) -> bool {
4615 (*port).is = 0xFFFFFFFF;
4616 let slot = ahci_find_cmd_slot(port);
4617 if slot == -1 { return false; }
4618
4619 let cmd_header = ((*port).clb + (slot as u64 * sizeof(AHCICmdHeader) as u64)) as ptr<AHCICmdHeader>;
4620 (*cmd_header).cfl_p_r_c = ((sizeof(AhciCmdFis) / 4) as u16) | 0x0040;
4621 (*cmd_header).prdtl = 1;
4622
4623 let cmd_table = (*cmd_header).ctba as ptr<AHCICmdTable>;
4624 memset(cmd_table as ptr<u8>, 0, sizeof(AHCICmdTable) as u64);
4625
4626 (*cmd_table).prdt_entry[0].dba = buf_phys;
4627 (*cmd_table).prdt_entry[0].dbc_i = (count * 512) - 1;
4628
4629 let fis = &(*cmd_table).cfis[0] as ptr<AhciCmdFis>;
4630 (*fis).fis_type = 0x27;
4631 (*fis).pmport_c = 0x80;
4632 (*fis).command = 0x35;
4633
4634 (*fis).lba0 = (start_lba & 0xFF) as u8;
4635 (*fis).lba1 = ((start_lba >> 8) & 0xFF) as u8;
4636 (*fis).lba2 = ((start_lba >> 16) & 0xFF) as u8;
4637 (*fis).device = 0x40;
4638
4639 (*fis).lba3 = ((start_lba >> 24) & 0xFF) as u8;
4640 (*fis).lba4 = ((start_lba >> 32) & 0xFF) as u8;
4641 (*fis).lba5 = ((start_lba >> 40) & 0xFF) as u8;
4642
4643 (*fis).count_l = (count & 0xFF) as u8;
4644 (*fis).count_h = ((count >> 8) & 0xFF) as u8;
4645
4646 while ((*port).tfd & (0x80 | 0x08)) != 0 { cpu_pause(); }
4647 (*port).ci = 1 << slot;
4648
4649 while true {
4650 if ((*port).ci & (1 << slot)) == 0 { break; }
4651 if ((*port).is & 0x40000000) != 0 { return false; }
4652 cpu_pause();
4653 }
4654 return true;
4655 }
4656 struct SignalContext {
4657 pending_mask: u32,
4658 blocked_mask: u32,
4659 handlers: [u64; 32],
4660 trampoline_addr: u64,
4661 saved_ctx: CpuContext,
4662 is_handling: bool,
4663 }
4664 struct ProcessControlBlockExt {
4665 base: ProcessControlBlock,
4666 sig_ctx: ptr<SignalContext>,
4667 }
4668 const SIGKILL: u32 = 9;
4669 const SIGSEGV: u32 = 11;
4670 const SIGTERM: u32 = 15;
4671 fn signal_init_process(proc: ptr<ProcessControlBlock>) {
4672 let proc_ext = proc as ptr<ProcessControlBlockExt>;
4673 (*proc_ext).sig_ctx = pmm_alloc_blocks(1) as ptr<SignalContext>;
4674 memset((*proc_ext).sig_ctx as ptr<u8>, 0, sizeof(SignalContext) as u64);
4675 }
4676 fn signal_send(target_pid: u64, signum: u32) -> bool {
4677 let mut curr = process_queue;
4678 while curr != 0 as ptr<ProcessControlBlock> {
4679 if (*curr).pid == target_pid {
4680 let proc_ext = curr as ptr<ProcessControlBlockExt>;
4681 if (*(*proc_ext).sig_ctx).is_handling { return false; }
4682 (*(*proc_ext).sig_ctx).pending_mask |= 1 << signum;
4683 if signum == SIGKILL {
4684 (*curr).state = 0;
4685 }
4686 return true;
4687 }
4688 curr = (*curr).next;
4689 }
4690 return false;
4691 }
4692 fn signal_check_pending() {
4693 if current_process == 0 as ptr<ProcessControlBlock> { return; }
4694 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
4695 let sig_ctx = (*proc_ext).sig_ctx;
4696
4697 if (*sig_ctx).is_handling { return; }
4698
4699 let active_sigs = (*sig_ctx).pending_mask & !(*sig_ctx).blocked_mask;
4700 if active_sigs == 0 { return; }
4701
4702 for i in 1..32 {
4703 if (active_sigs & (1 << i)) != 0 {
4704 (*sig_ctx).pending_mask &= !(1 << i);
4705 let handler = (*sig_ctx).handlers[i as usize];
4706 if handler != 0 {
4707 memcpy(&((*sig_ctx).saved_ctx) as ptr<u8>, (*current_process).context as ptr<u8>, sizeof(CpuContext) as u64);
4708 (*sig_ctx).is_handling = true;
4709 (*(*current_process).context).rip = handler;
4710 (*(*current_process).context).rdi = i as u64;
4711 let rsp = (*(*current_process).context).rsp;
4712 (*(*current_process).context).rsp = rsp - 128;
4713 return;
4714 }
4715 }
4716 }
4717 }
4718 fn signal_return() {
4719 if current_process == 0 as ptr<ProcessControlBlock> { return; }
4720 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
4721 let sig_ctx = (*proc_ext).sig_ctx;
4722 if !(*sig_ctx).is_handling { return; }
4723
4724 memcpy((*current_process).context as ptr<u8>, &((*sig_ctx).saved_ctx) as ptr<u8>, sizeof(CpuContext) as u64);
4725 (*sig_ctx).is_handling = false;
4726 }
4727 struct TcpCongestionExt {
4728 cwnd: u32,
4729 ssthresh: u32,
4730 dup_acks: u32,
4731 rtt: u32,
4732 rto: u32,
4733 in_fast_recovery: bool,
4734 }
4735 let mut global_tcp_cc: [TcpCongestionExt; 1024];
4736 fn tcp_cc_init(sock_idx: u32) {
4737 global_tcp_cc[sock_idx as usize].cwnd = 1460;
4738 global_tcp_cc[sock_idx as usize].ssthresh = 65535;
4739 global_tcp_cc[sock_idx as usize].dup_acks = 0;
4740 global_tcp_cc[sock_idx as usize].rto = 1000;
4741 global_tcp_cc[sock_idx as usize].in_fast_recovery = false;
4742 }
4743 fn tcp_cc_ack_received(sock_idx: u32, ack_diff: u32, is_dup: bool) {
4744 let cc = &global_tcp_cc[sock_idx as usize];
4745 if is_dup {
4746 (*cc).dup_acks = (*cc).dup_acks + 1;
4747 if (*cc).dup_acks == 3 {
4748 (*cc).ssthresh = (*cc).cwnd / 2;
4749 if (*cc).ssthresh < 1460 * 2 { (*cc).ssthresh = 1460 * 2; }
4750 (*cc).cwnd = (*cc).ssthresh + 3 * 1460;
4751 (*cc).in_fast_recovery = true;
4752 } else if (*cc).in_fast_recovery {
4753 (*cc).cwnd = (*cc).cwnd + 1460;
4754 }
4755 } else {
4756 (*cc).dup_acks = 0;
4757 if (*cc).in_fast_recovery {
4758 (*cc).cwnd = (*cc).ssthresh;
4759 (*cc).in_fast_recovery = false;
4760 } else {
4761 if (*cc).cwnd < (*cc).ssthresh {
4762 (*cc).cwnd = (*cc).cwnd + 1460;
4763 } else {
4764 (*cc).cwnd = (*cc).cwnd + (1460 * 1460) / (*cc).cwnd;
4765 }
4766 }
4767 }
4768 }
4769 fn tcp_cc_timeout(sock_idx: u32) {
4770 let cc = &global_tcp_cc[sock_idx as usize];
4771 (*cc).ssthresh = (*cc).cwnd / 2;
4772 if (*cc).ssthresh < 1460 * 2 { (*cc).ssthresh = 1460 * 2; }
4773 (*cc).cwnd = 1460;
4774 (*cc).dup_acks = 0;
4775 (*cc).in_fast_recovery = false;
4776 (*cc).rto = (*cc).rto * 2;
4777 if (*cc).rto > 64000 { (*cc).rto = 64000; }
4778 }
4779 struct VirtualConsole {
4780 id: u32,
4781 buffer_phys: u64,
4782 cursor_x: u32,
4783 cursor_y: u32,
4784 fg_color: u32,
4785 bg_color: u32,
4786 is_active: bool,
4787 }
4788 let mut global_vt_list: [VirtualConsole; 6];
4789 let mut vt_active_id: u32 = 0;
4790 let mut vt_lock: Spinlock;
4791 fn vt_init() {
4792 spin_init(&vt_lock);
4793 for i in 0..6 {
4794 global_vt_list[i].id = i as u32;
4795 global_vt_list[i].buffer_phys = pmm_alloc_blocks((comp_width * comp_height * 4) / PAGE_SIZE as u32 + 1);
4796 memset(global_vt_list[i].buffer_phys as ptr<u8>, 0, (comp_width * comp_height * 4) as u64);
4797 global_vt_list[i].cursor_x = 0;
4798 global_vt_list[i].cursor_y = 0;
4799 global_vt_list[i].fg_color = 0xFFFFFF;
4800 global_vt_list[i].bg_color = 0x000000;
4801 global_vt_list[i].is_active = false;
4802 }
4803 global_vt_list[0].is_active = true;
4804 }
4805 fn vt_switch(new_id: u32) {
4806 if new_id >= 6 || new_id == vt_active_id { return; }
4807 spin_lock(&vt_lock);
4808 global_vt_list[vt_active_id as usize].is_active = false;
4809 vt_active_id = new_id;
4810 global_vt_list[vt_active_id as usize].is_active = true;
4811 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);
4812 spin_unlock(&vt_lock);
4813 }
4814 fn vt_write_char(vt_id: u32, c: u8) {
4815 let vt = &global_vt_list[vt_id as usize];
4816 if c == 10 {
4817 (*vt).cursor_x = 0;
4818 (*vt).cursor_y = (*vt).cursor_y + system_font_h;
4819 } else {
4820 let buf = (*vt).buffer_phys as ptr<u32>;
4821 let glyph_offset = c as u64 * system_font_h as u64;
4822 let glyph = (system_font_ptr as u64 + glyph_offset) as ptr<u8>;
4823
4824 for cy in 0..system_font_h {
4825 let row = *(glyph + cy as u64);
4826 for cx in 0..system_font_w {
4827 let px = (*vt).cursor_x + cx;
4828 let py = (*vt).cursor_y + cy;
4829 if px < comp_width && py < comp_height {
4830 let p_idx = (py * comp_width + px) as u64;
4831 if (row & (0x80 >> cx)) != 0 {
4832 *(buf + p_idx) = (*vt).fg_color;
4833 } else {
4834 *(buf + p_idx) = (*vt).bg_color;
4835 }
4836 }
4837 }
4838 }
4839 (*vt).cursor_x = (*vt).cursor_x + system_font_w;
4840 if (*vt).cursor_x >= comp_width {
4841 (*vt).cursor_x = 0;
4842 (*vt).cursor_y = (*vt).cursor_y + system_font_h;
4843 }
4844 }
4845
4846 if (*vt).cursor_y >= comp_height {
4847 let buf = (*vt).buffer_phys as ptr<u32>;
4848 let row_bytes = (comp_width * system_font_h * 4) as u64;
4849 let total_bytes = (comp_width * comp_height * 4) as u64;
4850 memmove(buf as ptr<u8>, (buf as u64 + row_bytes) as ptr<u8>, total_bytes - row_bytes);
4851 memset((buf as u64 + total_bytes - row_bytes) as ptr<u8>, 0, row_bytes);
4852 (*vt).cursor_y = (*vt).cursor_y - system_font_h;
4853 }
4854
4855 if (*vt).is_active {
4856 memcpy(fb_ptr as ptr<u8>, (*vt).buffer_phys as ptr<u8>, (comp_width * comp_height * 4) as u64);
4857 }
4858 }
4859 struct AmlNode {
4860 opcode: u8,
4861 name: [u8; 4],
4862 length: u32,
4863 data_ptr: ptr<u8>,
4864 parent: ptr<AmlNode>,
4865 child: ptr<AmlNode>,
4866 next: ptr<AmlNode>,
4867 }
4868 let mut aml_root: ptr<AmlNode>;
4869 fn aml_parse_name(data: ptr<u8>) -> u32 {
4870 let mut offset: u32 = 0;
4871 if *data == 0x5C { offset = offset + 1; }
4872 if *(data as u64 + offset as u64) as ptr<u8> == 0x2E { offset = offset + 1; }
4873 offset = offset + 4;
4874 return offset;
4875 }
4876 fn aml_parse_pkg_length(data: ptr<u8>) -> (u32, u32) {
4877 let lead = *data;
4878 let byte_count = (lead >> 6) as u32;
4879 if byte_count == 0 {
4880 return ((lead & 0x3F) as u32, 1);
4881 }
4882 let mut length = (lead & 0x0F) as u32;
4883 for i in 0..byte_count {
4884 length |= (*(data as u64 + 1 + i as u64) as u32) << (4 + i * 8);
4885 }
4886 return (length, byte_count + 1);
4887 }
4888 fn aml_process_scope(parent: ptr<AmlNode>, data: ptr<u8>, limit: u32) {
4889 let mut offset: u32 = 0;
4890 while offset < limit {
4891 let opcode = *(data as u64 + offset as u64) as ptr<u8>;
4892 let mut parsed_len: u32 = 1;
4893
4894 if opcode == 0x10 {
4895 let (pkg_len, pkg_bytes) = aml_parse_pkg_length((data as u64 + offset as u64 + 1) as ptr<u8>);
4896 let name_offset = aml_parse_name((data as u64 + offset as u64 + 1 + pkg_bytes as u64) as ptr<u8>);
4897 parsed_len = 1 + pkg_bytes + pkg_len;
4898
4899 let node = pmm_alloc_blocks(1) as ptr<AmlNode>;
4900 memset(node as ptr<u8>, 0, sizeof(AmlNode) as u64);
4901 (*node).opcode = opcode;
4902 (*node).parent = parent;
4903
4904 if (*parent).child == 0 as ptr<AmlNode> {
4905 (*parent).child = node;
4906 } else {
4907 let mut curr = (*parent).child;
4908 while (*curr).next != 0 as ptr<AmlNode> { curr = (*curr).next; }
4909 (*curr).next = node;
4910 }
4911
4912 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);
4913 } else if opcode == 0x14 {
4914 let (pkg_len, pkg_bytes) = aml_parse_pkg_length((data as u64 + offset as u64 + 1) as ptr<u8>);
4915 parsed_len = 1 + pkg_bytes + pkg_len;
4916 } else if opcode == 0x08 {
4917 let name_offset = aml_parse_name((data as u64 + offset as u64 + 1) as ptr<u8>);
4918 parsed_len = 1 + name_offset + 1;
4919 } else {
4920 parsed_len = 1;
4921 }
4922 offset = offset + parsed_len;
4923 }
4924 }
4925 fn acpi_dsdt_init() {
4926 if acpi_fadt == 0 as ptr<FADTHeader> { return; }
4927 let dsdt_ptr = (*acpi_fadt).dsdt as u64 as ptr<ACPISDTHeader>;
4928 if !acpi_checksum(dsdt_ptr as ptr<u8>, (*dsdt_ptr).length) { return; }
4929
4930 aml_root = pmm_alloc_blocks(1) as ptr<AmlNode>;
4931 memset(aml_root as ptr<u8>, 0, sizeof(AmlNode) as u64);
4932
4933 let aml_data = (dsdt_ptr as u64 + sizeof(ACPISDTHeader) as u64) as ptr<u8>;
4934 let aml_len = (*dsdt_ptr).length - sizeof(ACPISDTHeader) as u32;
4935 aml_process_scope(aml_root, aml_data, aml_len);
4936 }
4937 const DOM_NODE_ELEMENT: u8 = 1;
4938 const DOM_NODE_TEXT: u8 = 2;
4939 struct HtmlAttribute {
4940 name: [u8; 32],
4941 value: [u8; 128],
4942 next: ptr<HtmlAttribute>,
4943 }
4944 struct DomNode {
4945 node_type: u8,
4946 tag_name: [u8; 32],
4947 text_content: ptr<u8>,
4948 attributes: ptr<HtmlAttribute>,
4949 parent: ptr<DomNode>,
4950 first_child: ptr<DomNode>,
4951 next_sibling: ptr<DomNode>,
4952 }
4953 let mut dom_node_pool: ptr<DomNode>;
4954 let mut dom_pool_idx: u32 = 0;
4955 fn html_init_parser() {
4956 dom_node_pool = pmm_alloc_blocks(64) as ptr<DomNode>;
4957 memset(dom_node_pool as ptr<u8>, 0, PAGE_SIZE * 64);
4958 dom_pool_idx = 0;
4959 }
4960 fn html_alloc_node() -> ptr<DomNode> {
4961 let node = (dom_node_pool as u64 + dom_pool_idx as u64 * sizeof(DomNode) as u64) as ptr<DomNode>;
4962 dom_pool_idx = dom_pool_idx + 1;
4963 return node;
4964 }
4965 fn html_skip_whitespace(html: ptr<u8>, pos: ptr<u32>) {
4966 while *(html as u64 + *pos as u64) as ptr<u8> == ' ' as u8 ||
4967 *(html as u64 + *pos as u64) as ptr<u8> == 10 ||
4968 *(html as u64 + *pos as u64) as ptr<u8> == 9 ||
4969 *(html as u64 + *pos as u64) as ptr<u8> == 13 {
4970 *pos = *pos + 1;
4971 }
4972 }
4973 fn html_parse_tag_name(html: ptr<u8>, pos: ptr<u32>, out_name: ptr<u8>) {
4974 let mut i: u32 = 0;
4975 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 &&
4976 *(html as u64 + *pos as u64) as ptr<u8> != ' ' as u8 &&
4977 *(html as u64 + *pos as u64) as ptr<u8> != '/' as u8 &&
4978 *(html as u64 + *pos as u64) as ptr<u8> != 0 &&
4979 i < 31 {
4980 *(out_name as u64 + i as u64) as ptr<u8> = *(html as u64 + *pos as u64) as ptr<u8>;
4981 *pos = *pos + 1;
4982 i = i + 1;
4983 }
4984 *(out_name as u64 + i as u64) as ptr<u8> = 0;
4985 }
4986 fn html_parse_node(html: ptr<u8>, pos: ptr<u32>, parent: ptr<DomNode>) -> ptr<DomNode> {
4987 html_skip_whitespace(html, pos);
4988 if *(html as u64 + *pos as u64) as ptr<u8> == 0 { return 0 as ptr<DomNode>; }
4989
4990 let node = html_alloc_node();
4991 (*node).parent = parent;
4992
4993 if *(html as u64 + *pos as u64) as ptr<u8> == '<' as u8 {
4994 *pos = *pos + 1;
4995 if *(html as u64 + *pos as u64) as ptr<u8> == '/' as u8 {
4996 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
4997 *pos = *pos + 1;
4998 }
4999 if *(html as u64 + *pos as u64) as ptr<u8> == '>' as u8 { *pos = *pos + 1; }
5000 return 0 as ptr<DomNode>;
5001 }
5002
5003 (*node).node_type = DOM_NODE_ELEMENT;
5004 html_parse_tag_name(html, pos, &((*node).tag_name[0]) as ptr<u8>);
5005
5006 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
5007 *pos = *pos + 1;
5008 }
5009
5010 let mut is_self_closing = false;
5011 if *(html as u64 + *pos as u64 - 1) as ptr<u8> == '/' as u8 {
5012 is_self_closing = true;
5013 }
5014
5015 if *(html as u64 + *pos as u64) as ptr<u8> == '>' as u8 { *pos = *pos + 1; }
5016
5017 if !is_self_closing {
5018 let mut last_child = 0 as ptr<DomNode>;
5019 loop {
5020 let child = html_parse_node(html, pos, node);
5021 if child == 0 as ptr<DomNode> { break; }
5022 if (*node).first_child == 0 as ptr<DomNode> {
5023 (*node).first_child = child;
5024 } else {
5025 (*last_child).next_sibling = child;
5026 }
5027 last_child = child;
5028 }
5029 }
5030 } else {
5031 (*node).node_type = DOM_NODE_TEXT;
5032 let mut start_pos = *pos;
5033 let mut len: u32 = 0;
5034 while *(html as u64 + *pos as u64) as ptr<u8> != '<' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
5035 *pos = *pos + 1;
5036 len = len + 1;
5037 }
5038 (*node).text_content = pmm_alloc_blocks((len / PAGE_SIZE as u32) + 1) as ptr<u8>;
5039 memcpy((*node).text_content, (html as u64 + start_pos as u64) as ptr<u8>, len as u64);
5040 *((*node).text_content as u64 + len as u64) as ptr<u8> = 0;
5041 }
5042
5043 return node;
5044 }
5045 const RAID_LEVEL_5: u32 = 5;
5046 const RAID_STRIPE_SIZE: u64 = 65536;
5047 struct RaidDisk {
5048 disk_id: u32,
5049 ahci_port: ptr<AHCIPortRegs>,
5050 is_online: bool,
5051 total_sectors: u64,
5052 }
5053 struct RaidArray {
5054 array_id: u32,
5055 level: u32,
5056 disks: [RaidDisk; 8],
5057 disk_count: u32,
5058 online_count: u32,
5059 total_capacity: u64,
5060 stripe_size: u64,
5061 }
5062 let mut global_raid_sys: RaidArray;
5063 fn raid_init_system() {
5064 global_raid_sys.array_id = 1;
5065 global_raid_sys.level = RAID_LEVEL_5;
5066 global_raid_sys.disk_count = 0;
5067 global_raid_sys.online_count = 0;
5068 global_raid_sys.stripe_size = RAID_STRIPE_SIZE;
5069 }
5070 fn raid_add_disk(port: ptr<AHCIPortRegs>, sectors: u64) {
5071 if global_raid_sys.disk_count < 8 {
5072 let idx = global_raid_sys.disk_count;
5073 global_raid_sys.disks[idx as usize].disk_id = idx;
5074 global_raid_sys.disks[idx as usize].ahci_port = port;
5075 global_raid_sys.disks[idx as usize].is_online = true;
5076 global_raid_sys.disks[idx as usize].total_sectors = sectors;
5077 global_raid_sys.disk_count = global_raid_sys.disk_count + 1;
5078 global_raid_sys.online_count = global_raid_sys.online_count + 1;
5079 global_raid_sys.total_capacity = (global_raid_sys.disk_count - 1) as u64 * sectors * 512;
5080 }
5081 }
5082 fn raid_compute_parity(buffers: ptr<u64>, count: u32, parity_buf: u64, size: u64) {
5083 let p_ptr = parity_buf as ptr<u64>;
5084 for i in 0..(size / 8) {
5085 let mut xor_val: u64 = 0;
5086 for d in 0..count {
5087 let buf_ptr = *(buffers + d as u64) as ptr<u64>;
5088 xor_val = xor_val ^ *(buf_ptr as u64 + i as u64 * 8) as ptr<u64>;
5089 }
5090 *(p_ptr as u64 + i as u64 * 8) as ptr<u64> = xor_val;
5091 }
5092 }
5093 fn raid_reconstruct_data(buffers: ptr<u64>, count: u32, parity_buf: u64, missing_idx: u32, size: u64) {
5094 let missing_ptr = *(buffers + missing_idx as u64) as ptr<u64>;
5095 let p_ptr = parity_buf as ptr<u64>;
5096 for i in 0..(size / 8) {
5097 let mut xor_val: u64 = *(p_ptr as u64 + i as u64 * 8) as ptr<u64>;
5098 for d in 0..count {
5099 if d != missing_idx {
5100 let buf_ptr = *(buffers + d as u64) as ptr<u64>;
5101 xor_val = xor_val ^ *(buf_ptr as u64 + i as u64 * 8) as ptr<u64>;
5102 }
5103 }
5104 *(missing_ptr as u64 + i as u64 * 8) as ptr<u64> = xor_val;
5105 }
5106 }
5107 fn raid_write_stripe(stripe_lba: u64, data_buffers: ptr<u64>) {
5108 let disk_cnt = global_raid_sys.disk_count;
5109 let parity_disk = (stripe_lba / (RAID_STRIPE_SIZE / 512)) % disk_cnt as u64;
5110
5111 let parity_buf = pmm_alloc_blocks(RAID_STRIPE_SIZE / PAGE_SIZE);
5112 raid_compute_parity(data_buffers, disk_cnt - 1, parity_buf, RAID_STRIPE_SIZE);
5113
5114 let mut data_idx = 0;
5115 for i in 0..disk_cnt {
5116 let port = global_raid_sys.disks[i as usize].ahci_port;
5117 if i as u64 == parity_disk {
5118 ahci_write_sectors(port, stripe_lba, (RAID_STRIPE_SIZE / 512) as u32, parity_buf);
5119 } else {
5120 let d_buf = *(data_buffers + data_idx as u64);
5121 ahci_write_sectors(port, stripe_lba, (RAID_STRIPE_SIZE / 512) as u32, d_buf);
5122 data_idx = data_idx + 1;
5123 }
5124 }
5125 pmm_free_blocks(parity_buf, RAID_STRIPE_SIZE / PAGE_SIZE);
5126 }
5127 struct CpuRunQueue {
5128 core_id: u32,
5129 head: ptr<ProcessControlBlock>,
5130 tail: ptr<ProcessControlBlock>,
5131 load_factor: u32,
5132 lock: Spinlock,
5133 }
5134 let mut global_run_queues: [CpuRunQueue; 256];
5135 fn smp_balancer_init() {
5136 for i in 0..smp_core_count {
5137 global_run_queues[i as usize].core_id = smp_cores[i as usize].apic_id as u32;
5138 global_run_queues[i as usize].head = 0 as ptr<ProcessControlBlock>;
5139 global_run_queues[i as usize].tail = 0 as ptr<ProcessControlBlock>;
5140 global_run_queues[i as usize].load_factor = 0;
5141 spin_init(&(global_run_queues[i as usize].lock));
5142 }
5143 }
5144 fn smp_enqueue_task(core_idx: u32, task: ptr<ProcessControlBlock>) {
5145 let rq = &global_run_queues[core_idx as usize];
5146 spin_lock(&((*rq).lock));
5147 (*task).next = 0 as ptr<ProcessControlBlock>;
5148 if (*rq).tail == 0 as ptr<ProcessControlBlock> {
5149 (*rq).head = task;
5150 (*rq).tail = task;
5151 } else {
5152 (*((*rq).tail)).next = task;
5153 (*rq).tail = task;
5154 }
5155 (*rq).load_factor = (*rq).load_factor + 1;
5156 spin_unlock(&((*rq).lock));
5157 }
5158 fn smp_dequeue_task(core_idx: u32) -> ptr<ProcessControlBlock> {
5159 let rq = &global_run_queues[core_idx as usize];
5160 spin_lock(&((*rq).lock));
5161 if (*rq).head == 0 as ptr<ProcessControlBlock> {
5162 spin_unlock(&((*rq).lock));
5163 return 0 as ptr<ProcessControlBlock>;
5164 }
5165 let task = (*rq).head;
5166 (*rq).head = (*task).next;
5167 if (*rq).head == 0 as ptr<ProcessControlBlock> {
5168 (*rq).tail = 0 as ptr<ProcessControlBlock>;
5169 }
5170 (*rq).load_factor = (*rq).load_factor - 1;
5171 spin_unlock(&((*rq).lock));
5172 return task;
5173 }
5174 fn smp_balance_load() {
5175 let mut max_load: u32 = 0;
5176 let mut min_load: u32 = 0xFFFFFFFF;
5177 let mut busiest_core: u32 = 0;
5178 let mut idlest_core: u32 = 0;
5179
5180 for i in 0..smp_core_count {
5181 let load = global_run_queues[i as usize].load_factor;
5182 if load > max_load { max_load = load; busiest_core = i; }
5183 if load < min_load { min_load = load; idlest_core = i; }
5184 }
5185
5186 if max_load > min_load + 2 {
5187 let task = smp_dequeue_task(busiest_core);
5188 if task != 0 as ptr<ProcessControlBlock> {
5189 smp_enqueue_task(idlest_core, task);
5190 }
5191 }
5192 }
5193 struct WaylandBuffer {
5194 shm_id: u64,
5195 width: u32,
5196 height: u32,
5197 stride: u32,
5198 format: u32,
5199 }
5200 struct WaylandSurface {
5201 surface_id: u32,
5202 owner_pid: u64,
5203 buffer: ptr<WaylandBuffer>,
5204 x: i32,
5205 y: i32,
5206 z_order: u32,
5207 is_mapped: bool,
5208 next: ptr<WaylandSurface>,
5209 }
5210 let mut display_srv_surfaces: ptr<WaylandSurface>;
5211 let mut display_srv_next_id: u32 = 1000;
5212 fn display_srv_create_surface(pid: u64) -> u32 {
5213 let surf = pmm_alloc_blocks(1) as ptr<WaylandSurface>;
5214 memset(surf as ptr<u8>, 0, sizeof(WaylandSurface) as u64);
5215 (*surf).surface_id = display_srv_next_id;
5216 display_srv_next_id = display_srv_next_id + 1;
5217 (*surf).owner_pid = pid;
5218 (*surf).is_mapped = false;
5219 (*surf).next = display_srv_surfaces;
5220 display_srv_surfaces = surf;
5221 return (*surf).surface_id;
5222 }
5223 fn display_srv_attach_buffer(surface_id: u32, shm_id: u64, w: u32, h: u32) {
5224 let mut curr = display_srv_surfaces;
5225 while curr != 0 as ptr<WaylandSurface> {
5226 if (*curr).surface_id == surface_id {
5227 let buf = pmm_alloc_blocks(1) as ptr<WaylandBuffer>;
5228 (*buf).shm_id = shm_id;
5229 (*buf).width = w;
5230 (*buf).height = h;
5231 (*buf).stride = w * 4;
5232 (*buf).format = 1;
5233 (*curr).buffer = buf;
5234 return;
5235 }
5236 curr = (*curr).next;
5237 }
5238 }
5239 fn display_srv_commit(surface_id: u32, x: i32, y: i32) {
5240 let mut curr = display_srv_surfaces;
5241 while curr != 0 as ptr<WaylandSurface> {
5242 if (*curr).surface_id == surface_id {
5243 (*curr).x = x;
5244 (*curr).y = y;
5245 (*curr).is_mapped = true;
5246 return;
5247 }
5248 curr = (*curr).next;
5249 }
5250 }
5251 fn display_srv_composite() {
5252 let bg_color = 0x1A1A1A;
5253 comp_draw_rect(comp_root_window, 0, 0, comp_width, comp_height, bg_color);
5254
5255 let mut curr = display_srv_surfaces;
5256 while curr != 0 as ptr<WaylandSurface> {
5257 if (*curr).is_mapped && (*curr).buffer != 0 as ptr<WaylandBuffer> {
5258 let buf_info = (*curr).buffer;
5259 let mut phys_base: u64 = 0;
5260 for i in 0..256 {
5261 if global_shm_table[i].shm_id == (*buf_info).shm_id {
5262 phys_base = global_shm_table[i].phys_base;
5263 break;
5264 }
5265 }
5266 if phys_base != 0 {
5267 let p_pixels = phys_base as ptr<u32>;
5268 for h in 0..(*buf_info).height {
5269 for w in 0..(*buf_info).width {
5270 let sx = (*curr).x + w as i32;
5271 let sy = (*curr).y + h as i32;
5272 if sx >= 0 && sx < comp_width as i32 && sy >= 0 && sy < comp_height as i32 {
5273 let color = *(p_pixels as u64 + (h * (*buf_info).width + w) as u64 * 4) as ptr<u32>;
5274 if (*color & 0xFF000000) != 0 {
5275 *(comp_back_buffer as u64 + (sy as u32 * comp_width + sx as u32) as u64 * 4) as ptr<u32> = *color;
5276 }
5277 }
5278 }
5279 }
5280 }
5281 }
5282 curr = (*curr).next;
5283 }
5284 memcpy(fb_ptr as ptr<u8>, comp_back_buffer as ptr<u8>, (comp_width * comp_height * 4) as u64);
5285 }
5286 struct XhciIsochTrb {
5287 data_buffer_ptr: u64,
5288 tlc_tdpc_int_cc: u32,
5289 flags: u32,
5290 }
5291 fn xhci_queue_isoch_transfer(ring: ptr<u8>, phys_buf: u64, length: u32, frame_id: u32) {
5292 let trb = ring as ptr<XhciIsochTrb>;
5293 (*trb).data_buffer_ptr = phys_buf;
5294 (*trb).tlc_tdpc_int_cc = length & 0x1FFFF;
5295 (*trb).flags = (frame_id << 20) | (32 << 10) | 1;
5296 }
5297 fn math_exp(x: f32) -> f32 {
5298 let mut sum: f32 = 1.0;
5299 let mut term: f32 = 1.0;
5300 for i in 1..20 {
5301 term = term * x / (i as f32);
5302 sum = sum + term;
5303 }
5304 return sum;
5305 }
5306 struct Tensor2D {
5307 rows: u32,
5308 cols: u32,
5309 data: ptr<f32>,
5310 }
5311 fn tensor_create(rows: u32, cols: u32) -> ptr<Tensor2D> {
5312 let t = pmm_alloc_blocks(1) as ptr<Tensor2D>;
5313 (*t).rows = rows;
5314 (*t).cols = cols;
5315 let bytes = rows * cols * 4;
5316 let pages = (bytes / PAGE_SIZE as u32) + 1;
5317 (*t).data = pmm_alloc_blocks(pages as u64) as ptr<f32>;
5318 memset((*t).data as ptr<u8>, 0, (pages * PAGE_SIZE as u32) as u64);
5319 return t;
5320 }
5321 fn tensor_destroy(t: ptr<Tensor2D>) {
5322 let bytes = (*t).rows * (*t).cols * 4;
5323 let pages = (bytes / PAGE_SIZE as u32) + 1;
5324 pmm_free_blocks((*t).data as u64, pages as u64);
5325 pmm_free_blocks(t as u64, 1);
5326 }
5327 fn tensor_matmul(a: ptr<Tensor2D>, b: ptr<Tensor2D>, out: ptr<Tensor2D>) {
5328 if (*a).cols != (*b).rows { return; }
5329 if (*out).rows != (*a).rows || (*out).cols != (*b).cols { return; }
5330
5331 for i in 0..(*a).rows {
5332 for j in 0..(*b).cols {
5333 let mut sum: f32 = 0.0;
5334 for k in 0..(*a).cols {
5335 let val_a = *((*a).data as u64 + (i * (*a).cols + k) as u64 * 4) as ptr<f32>;
5336 let val_b = *((*b).data as u64 + (k * (*b).cols + j) as u64 * 4) as ptr<f32>;
5337 sum = sum + (*val_a * *val_b);
5338 }
5339 *((*out).data as u64 + (i * (*out).cols + j) as u64 * 4) as ptr<f32> = sum;
5340 }
5341 }
5342 }
5343 fn tensor_relu(t: ptr<Tensor2D>) {
5344 let total = (*t).rows * (*t).cols;
5345 for i in 0..total {
5346 let val_ptr = ((*t).data as u64 + i as u64 * 4) as ptr<f32>;
5347 if *val_ptr < 0.0 {
5348 *val_ptr = 0.0;
5349 }
5350 }
5351 }
5352 fn tensor_sigmoid(t: ptr<Tensor2D>) {
5353 let total = (*t).rows * (*t).cols;
5354 for i in 0..total {
5355 let val_ptr = ((*t).data as u64 + i as u64 * 4) as ptr<f32>;
5356 let e_x = math_exp(-(*val_ptr));
5357 *val_ptr = 1.0 / (1.0 + e_x);
5358 }
5359 }
5360 fn tensor_softmax(t: ptr<Tensor2D>) {
5361 for i in 0..(*t).rows {
5362 let mut max_val = *((*t).data as u64 + (i * (*t).cols) as u64 * 4) as ptr<f32>;
5363 for j in 1..(*t).cols {
5364 let v = *((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5365 if v > max_val { max_val = v; }
5366 }
5367
5368 let mut sum_exp: f32 = 0.0;
5369 for j in 0..(*t).cols {
5370 let val_ptr = ((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5371 let e = math_exp(*val_ptr - max_val);
5372 *val_ptr = e;
5373 sum_exp = sum_exp + e;
5374 }
5375
5376 for j in 0..(*t).cols {
5377 let val_ptr = ((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5378 *val_ptr = *val_ptr / sum_exp;
5379 }
5380 }
5381 }
5382 const FW_ACTION_ALLOW: u8 = 0;
5383 const FW_ACTION_DROP: u8 = 1;
5384 const FW_ACTION_REJECT: u8 = 2;
5385 const FW_PROTO_TCP: u8 = 6;
5386 const FW_PROTO_UDP: u8 = 17;
5387 const FW_PROTO_ICMP: u8 = 1;
5388 struct FirewallRule {
5389 src_ip: Ipv4Addr,
5390 src_mask: Ipv4Addr,
5391 dst_ip: Ipv4Addr,
5392 dst_mask: Ipv4Addr,
5393 src_port_min: u16,
5394 src_port_max: u16,
5395 dst_port_min: u16,
5396 dst_port_max: u16,
5397 protocol: u8,
5398 action: u8,
5399 is_active: bool,
5400 hit_count: u64,
5401 }
5402 struct FwConnectionState {
5403 src_ip: Ipv4Addr,
5404 dst_ip: Ipv4Addr,
5405 src_port: u16,
5406 dst_port: u16,
5407 protocol: u8,
5408 state: u8,
5409 last_activity: u64,
5410 is_active: bool,
5411 }
5412 let mut global_fw_rules: [FirewallRule; 512];
5413 let mut global_fw_states: [FwConnectionState; 4096];
5414 let mut fw_lock: Spinlock;
5415 let mut fw_enabled: bool = true;
5416 let mut fw_syn_cookie_secret: u32 = 0;
5417 fn fw_init() {
5418 spin_init(&fw_lock);
5419 for i in 0..512 { global_fw_rules[i].is_active = false; }
5420 for i in 0..4096 { global_fw_states[i].is_active = false; }
5421 fw_syn_cookie_secret = rand_next() as u32;
5422 }
5423 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 {
5424 spin_lock(&fw_lock);
5425 for i in 0..512 {
5426 if !global_fw_rules[i].is_active {
5427 global_fw_rules[i].src_ip = src_ip;
5428 global_fw_rules[i].src_mask = src_mask;
5429 global_fw_rules[i].dst_ip = dst_ip;
5430 global_fw_rules[i].dst_mask = dst_mask;
5431 global_fw_rules[i].src_port_min = 0;
5432 global_fw_rules[i].src_port_max = 65535;
5433 global_fw_rules[i].dst_port_min = p_min;
5434 global_fw_rules[i].dst_port_max = p_max;
5435 global_fw_rules[i].protocol = proto;
5436 global_fw_rules[i].action = action;
5437 global_fw_rules[i].hit_count = 0;
5438 global_fw_rules[i].is_active = true;
5439 spin_unlock(&fw_lock);
5440 return true;
5441 }
5442 }
5443 spin_unlock(&fw_lock);
5444 return false;
5445 }
5446 fn fw_match_ip(ip: Ipv4Addr, rule_ip: Ipv4Addr, mask: Ipv4Addr) -> bool {
5447 for i in 0..4 {
5448 if (ip.addr[i] & mask.addr[i]) != (rule_ip.addr[i] & mask.addr[i]) {
5449 return false;
5450 }
5451 }
5452 return true;
5453 }
5454 fn fw_track_connection(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, src_port: u16, dst_port: u16, proto: u8, tcp_flags: u16) -> bool {
5455 for i in 0..4096 {
5456 if global_fw_states[i].is_active {
5457 let mut match_fwd = true;
5458 let mut match_rev = true;
5459 for j in 0..4 {
5460 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; }
5461 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; }
5462 }
5463 if global_fw_states[i].protocol != proto { match_fwd = false; match_rev = false; }
5464 if global_fw_states[i].src_port != src_port || global_fw_states[i].dst_port != dst_port { match_fwd = false; }
5465 if global_fw_states[i].src_port != dst_port || global_fw_states[i].dst_port != src_port { match_rev = false; }
5466
5467 if match_fwd || match_rev {
5468 global_fw_states[i].last_activity = current_time_tick;
5469 if proto == FW_PROTO_TCP && (tcp_flags & 0x01) != 0 {
5470 global_fw_states[i].is_active = false;
5471 }
5472 return true;
5473 }
5474 }
5475 }
5476
5477 if proto == FW_PROTO_TCP && (tcp_flags & 0x02) != 0 && (tcp_flags & 0x10) == 0 {
5478 for i in 0..4096 {
5479 if !global_fw_states[i].is_active {
5480 global_fw_states[i].src_ip = src_ip;
5481 global_fw_states[i].dst_ip = dst_ip;
5482 global_fw_states[i].src_port = src_port;
5483 global_fw_states[i].dst_port = dst_port;
5484 global_fw_states[i].protocol = proto;
5485 global_fw_states[i].state = 1;
5486 global_fw_states[i].last_activity = current_time_tick;
5487 global_fw_states[i].is_active = true;
5488 return true;
5489 }
5490 }
5491 }
5492
5493 return false;
5494 }
5495 fn fw_inspect_packet(packet: ptr<u8>, length: u32) -> u8 {
5496 if !fw_enabled { return FW_ACTION_ALLOW; }
5497
5498 let eth = packet as ptr<EthernetHeader>;
5499 if htons((*eth).ethertype) != 0x0800 { return FW_ACTION_ALLOW; }
5500
5501 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
5502 let proto = (*iph).protocol;
5503 let mut src_port: u16 = 0;
5504 let mut dst_port: u16 = 0;
5505 let mut tcp_flags: u16 = 0;
5506
5507 if proto == FW_PROTO_TCP {
5508 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
5509 src_port = htons((*tcph).src_port);
5510 dst_port = htons((*tcph).dest_port);
5511 tcp_flags = htons((*tcph).data_offset_flags) & 0x01FF;
5512 } else if proto == FW_PROTO_UDP {
5513 let udph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<UdpHeader>;
5514 src_port = htons((*udph).src_port);
5515 dst_port = htons((*udph).dest_port);
5516 }
5517
5518 spin_lock(&fw_lock);
5519 let tracked = fw_track_connection((*iph).src_ip, (*iph).dest_ip, src_port, dst_port, proto, tcp_flags);
5520 if tracked {
5521 spin_unlock(&fw_lock);
5522 return FW_ACTION_ALLOW;
5523 }
5524
5525 let mut final_action = FW_ACTION_DROP;
5526
5527 for i in 0..512 {
5528 if global_fw_rules[i].is_active {
5529 let mut match_rule = true;
5530 if global_fw_rules[i].protocol != 0 && global_fw_rules[i].protocol != proto { match_rule = false; }
5531 if !fw_match_ip((*iph).src_ip, global_fw_rules[i].src_ip, global_fw_rules[i].src_mask) { match_rule = false; }
5532 if !fw_match_ip((*iph).dest_ip, global_fw_rules[i].dst_ip, global_fw_rules[i].dst_mask) { match_rule = false; }
5533 if proto == FW_PROTO_TCP || proto == FW_PROTO_UDP {
5534 if src_port < global_fw_rules[i].src_port_min || src_port > global_fw_rules[i].src_port_max { match_rule = false; }
5535 if dst_port < global_fw_rules[i].dst_port_min || dst_port > global_fw_rules[i].dst_port_max { match_rule = false; }
5536 }
5537
5538 if match_rule {
5539 global_fw_rules[i].hit_count = global_fw_rules[i].hit_count + 1;
5540 final_action = global_fw_rules[i].action;
5541 break;
5542 }
5543 }
5544 }
5545
5546 spin_unlock(&fw_lock);
5547 return final_action;
5548 }
5549 struct HciCommandHeader {
5550 opcode: u16,
5551 param_length: u8,
5552 }
5553 struct HciAclHeader {
5554 handle_flags: u16,
5555 data_length: u16,
5556 }
5557 struct L2capHeader {
5558 length: u16,
5559 channel_id: u16,
5560 }
5561 const HCI_CMD_RESET: u16 = 0x0C03;
5562 const HCI_CMD_READ_BD_ADDR: u16 = 0x1009;
5563 const HCI_CMD_INQUIRY: u16 = 0x0401;
5564 const HCI_CMD_CREATE_CONNECTION: u16 = 0x0405;
5565 let mut bt_hci_tx_ring: ptr<u8>;
5566 let mut bt_hci_rx_ring: ptr<u8>;
5567 fn bt_init_controller() {
5568 bt_hci_tx_ring = pmm_alloc_blocks(1) as ptr<u8>;
5569 bt_hci_rx_ring = pmm_alloc_blocks(1) as ptr<u8>;
5570 memset(bt_hci_tx_ring, 0, PAGE_SIZE);
5571 memset(bt_hci_rx_ring, 0, PAGE_SIZE);
5572 }
5573 fn bt_send_hci_command(opcode: u16, params: ptr<u8>, param_len: u8) {
5574 let hdr = bt_hci_tx_ring as ptr<HciCommandHeader>;
5575 (*hdr).opcode = opcode;
5576 (*hdr).param_length = param_len;
5577 if param_len > 0 {
5578 let payload = (bt_hci_tx_ring as u64 + sizeof(HciCommandHeader) as u64) as ptr<u8>;
5579 memcpy(payload, params, param_len as u64);
5580 }
5581 let total_len = sizeof(HciCommandHeader) as u64 + param_len as u64;
5582 xhci_queue_isoch_transfer(0 as ptr<u8>, bt_hci_tx_ring as u64, total_len as u32, 0);
5583 }
5584 fn bt_send_l2cap(handle: u16, cid: u16, data: ptr<u8>, len: u16) {
5585 let acl_hdr = bt_hci_tx_ring as ptr<HciAclHeader>;
5586 (*acl_hdr).handle_flags = handle | 0x2000;
5587 (*acl_hdr).data_length = sizeof(L2capHeader) as u16 + len;
5588
5589 let l2cap_hdr = (bt_hci_tx_ring as u64 + sizeof(HciAclHeader) as u64) as ptr<L2capHeader>;
5590 (*l2cap_hdr).length = len;
5591 (*l2cap_hdr).channel_id = cid;
5592
5593 let payload = (bt_hci_tx_ring as u64 + sizeof(HciAclHeader) as u64 + sizeof(L2capHeader) as u64) as ptr<u8>;
5594 memcpy(payload, data, len as u64);
5595
5596 let total_len = sizeof(HciAclHeader) as u64 + (*acl_hdr).data_length as u64;
5597 xhci_queue_isoch_transfer(0 as ptr<u8>, bt_hci_tx_ring as u64, total_len as u32, 0);
5598 }
5599 struct Jbd2Header {
5600 h_magic: u32,
5601 h_blocktype: u32,
5602 h_sequence: u32,
5603 }
5604 struct Jbd2BlockTag {
5605 t_blocknr: u32,
5606 t_flags: u16,
5607 }
5608 const JBD2_MAGIC_NUMBER: u32 = 0xC03B3998;
5609 const JBD2_DESCRIPTOR_BLOCK: u32 = 1;
5610 const JBD2_COMMIT_BLOCK: u32 = 2;
5611 const JBD2_SUPERBLOCK_V1: u32 = 3;
5612 const JBD2_SUPERBLOCK_V2: u32 = 4;
5613 const JBD2_REVOKE_BLOCK: u32 = 5;
5614 let mut jbd2_journal_start: u32 = 0;
5615 let mut jbd2_journal_end: u32 = 0;
5616 let mut jbd2_current_seq: u32 = 1;
5617 fn jbd2_init(start_block: u32, end_block: u32) {
5618 jbd2_journal_start = start_block;
5619 jbd2_journal_end = end_block;
5620 jbd2_current_seq = 1;
5621 }
5622 fn jbd2_start_transaction() -> u32 {
5623 let seq = jbd2_current_seq;
5624 jbd2_current_seq = jbd2_current_seq + 1;
5625 return seq;
5626 }
5627 fn jbd2_write_descriptor(seq: u32, target_blocks: ptr<u32>, count: u32) -> u32 {
5628 let buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
5629 memset(buf, 0, ext2_block_size as u64);
5630
5631 let hdr = buf as ptr<Jbd2Header>;
5632 (*hdr).h_magic = htonl(JBD2_MAGIC_NUMBER);
5633 (*hdr).h_blocktype = htonl(JBD2_DESCRIPTOR_BLOCK);
5634 (*hdr).h_sequence = htonl(seq);
5635
5636 let mut offset = sizeof(Jbd2Header) as u64;
5637 for i in 0..count {
5638 let tag = (buf as u64 + offset) as ptr<Jbd2BlockTag>;
5639 (*tag).t_blocknr = htonl(*(target_blocks as u64 + i as u64 * 4) as ptr<u32>);
5640 (*tag).t_flags = 0;
5641 if i == count - 1 { (*tag).t_flags = htons(8); }
5642 offset = offset + sizeof(Jbd2BlockTag) as u64;
5643 }
5644
5645 let lba = fat32_cluster_to_lba(jbd2_journal_start);
5646 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, lba as u64, (ext2_block_size / 512) as u32, buf as u64);
5647 pmm_free_blocks(buf as u64, (ext2_block_size / PAGE_SIZE as u32) + 1);
5648 return jbd2_journal_start + 1;
5649 }
5650 fn jbd2_commit_transaction(seq: u32, cur_journal_block: u32) {
5651 let buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
5652 memset(buf, 0, ext2_block_size as u64);
5653
5654 let hdr = buf as ptr<Jbd2Header>;
5655 (*hdr).h_magic = htonl(JBD2_MAGIC_NUMBER);
5656 (*hdr).h_blocktype = htonl(JBD2_COMMIT_BLOCK);
5657 (*hdr).h_sequence = htonl(seq);
5658
5659 let lba = fat32_cluster_to_lba(cur_journal_block);
5660 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, lba as u64, (ext2_block_size / 512) as u32, buf as u64);
5661 pmm_free_blocks(buf as u64, (ext2_block_size / PAGE_SIZE as u32) + 1);
5662 }
5663 struct UacFormatTypeI {
5664 length: u8,
5665 descriptor_type: u8,
5666 descriptor_subtype: u8,
5667 format_type: u8,
5668 num_channels: u8,
5669 subframe_size: u8,
5670 bit_resolution: u8,
5671 sample_freq_type: u8,
5672 sample_freq: [u8; 3],
5673 }
5674 fn uac_set_sample_rate(ep_addr: u8, rate: u32) {
5675 let mut setup_packet: [u8; 8];
5676 setup_packet[0] = 0x22;
5677 setup_packet[1] = 0x01;
5678 setup_packet[2] = 0x01;
5679 setup_packet[3] = 0x01;
5680 setup_packet[4] = ep_addr;
5681 setup_packet[5] = 0x00;
5682 setup_packet[6] = 0x03;
5683 setup_packet[7] = 0x00;
5684
5685 let mut data_packet: [u8; 3];
5686 data_packet[0] = (rate & 0xFF) as u8;
5687 data_packet[1] = ((rate >> 8) & 0xFF) as u8;
5688 data_packet[2] = ((rate >> 16) & 0xFF) as u8;
5689 }
5690 fn hw_rdrand_64() -> u64 {
5691 let mut val: u64 = 0;
5692 let mut retry: u32 = 10;
5693 while retry > 0 {
5694 let mut success: u8 = 0;
5695 asm {
5696 "rdrand rax\n setc bl"
5697 out rax = val;
5698 out bl = success;
5699 }
5700 if success == 1 { return val; }
5701 retry = retry - 1;
5702 }
5703 return rand_next();
5704 }
5705 fn hw_rdseed_64() -> u64 {
5706 let mut val: u64 = 0;
5707 let mut retry: u32 = 10;
5708 while retry > 0 {
5709 let mut success: u8 = 0;
5710 asm {
5711 "rdseed rax\n setc bl"
5712 out rax = val;
5713 out bl = success;
5714 }
5715 if success == 1 { return val; }
5716 retry = retry - 1;
5717 }
5718 return hw_rdrand_64();
5719 }
5720 struct VmxonRegion {
5721 revision_id: u32,
5722 data: [u8; 4092],
5723 }
5724 struct VmcsRegion {
5725 revision_id: u32,
5726 abort_indicator: u32,
5727 data: [u8; 4088],
5728 }
5729 let mut vmx_enabled: bool = false;
5730 let mut vmxon_region_phys: u64 = 0;
5731 fn vmx_check_support() -> bool {
5732 let mut ecx: u32 = 0;
5733 asm {
5734 "mov eax, 1\n cpuid"
5735 out ecx = ecx;
5736 }
5737 return (ecx & (1 << 5)) != 0;
5738 }
5739 fn vmx_enable() {
5740 let mut cr4: u64 = 0;
5741 asm { "mov %0, cr4" out cr4 = cr4; }
5742 cr4 |= (1 << 13);
5743 asm { "mov cr4, %0" in "%0" = cr4; }
5744
5745 let feature_control = rdmsr(0x3A);
5746 if (feature_control & 1) == 0 {
5747 wrmsr(0x3A, feature_control | 5);
5748 }
5749 }
5750 fn vmx_init() {
5751 if !vmx_check_support() { return; }
5752 vmx_enable();
5753
5754 let vmx_basic = rdmsr(0x480);
5755 let revision_id = (vmx_basic & 0xFFFFFFFF) as u32;
5756
5757 vmxon_region_phys = pmm_alloc_blocks(1);
5758 memset(vmxon_region_phys as ptr<u8>, 0, PAGE_SIZE);
5759 *(vmxon_region_phys as ptr<u32>) = revision_id;
5760
5761 let mut success: u8 = 0;
5762 asm {
5763 "vmxon [%0]\n setz al\n setc ah"
5764 in "%0" = &vmxon_region_phys;
5765 out al = success;
5766 }
5767 if success == 0 { vmx_enabled = true; }
5768 }
5769 fn vmx_create_vm() -> ptr<VmcsRegion> {
5770 if !vmx_enabled { return 0 as ptr<VmcsRegion>; }
5771
5772 let vmx_basic = rdmsr(0x480);
5773 let revision_id = (vmx_basic & 0xFFFFFFFF) as u32;
5774
5775 let vmcs_phys = pmm_alloc_blocks(1);
5776 memset(vmcs_phys as ptr<u8>, 0, PAGE_SIZE);
5777 *(vmcs_phys as ptr<u32>) = revision_id;
5778
5779 asm {
5780 "vmclear [%0]"
5781 in "%0" = &vmcs_phys;
5782 }
5783
5784 asm {
5785 "vmptrld [%0]"
5786 in "%0" = &vmcs_phys;
5787 }
5788
5789 return vmcs_phys as ptr<VmcsRegion>;
5790 }
5791 struct WasmModule {
5792 magic: u32,
5793 version: u32,
5794 memory_pages: u32,
5795 memory_base: u64,
5796 code_base: ptr<u8>,
5797 code_size: u64,
5798 }
5799 const WASM_MAGIC: u32 = 0x6D736100;
5800 fn wasm_parse_leb128(data: ptr<u8>, offset: ptr<u64>) -> u64 {
5801 let mut result: u64 = 0;
5802 let mut shift: u64 = 0;
5803 loop {
5804 let byte = *(data as u64 + *offset) as ptr<u8>;
5805 *offset = *offset + 1;
5806 result |= ((*byte & 0x7F) as u64) << shift;
5807 shift = shift + 7;
5808 if (*byte & 0x80) == 0 { break; }
5809 }
5810 return result;
5811 }
5812 fn wasm_load_module(wasm_data: ptr<u8>, size: u64) -> ptr<WasmModule> {
5813 let magic = *(wasm_data as ptr<u32>);
5814 if magic != WASM_MAGIC { return 0 as ptr<WasmModule>; }
5815
5816 let version = *((wasm_data as u64 + 4) as ptr<u32>);
5817 if version != 1 { return 0 as ptr<WasmModule>; }
5818
5819 let module = pmm_alloc_blocks(1) as ptr<WasmModule>;
5820 memset(module as ptr<u8>, 0, sizeof(WasmModule) as u64);
5821 (*module).magic = magic;
5822 (*module).version = version;
5823
5824 let mut offset: u64 = 8;
5825 while offset < size {
5826 let section_id = *(wasm_data as u64 + offset) as ptr<u8>;
5827 offset = offset + 1;
5828 let section_size = wasm_parse_leb128(wasm_data, &offset);
5829
5830 if *section_id == 10 {
5831 (*module).code_base = (wasm_data as u64 + offset) as ptr<u8>;
5832 (*module).code_size = section_size;
5833 } else if *section_id == 5 {
5834 let _num_mems = wasm_parse_leb128(wasm_data, &offset);
5835 let flags = wasm_parse_leb128(wasm_data, &offset);
5836 let initial_pages = wasm_parse_leb128(wasm_data, &offset);
5837 (*module).memory_pages = initial_pages as u32;
5838 (*module).memory_base = pmm_alloc_blocks(initial_pages * 16);
5839 memset((*module).memory_base as ptr<u8>, 0, initial_pages * 65536);
5840 }
5841 offset = offset + section_size;
5842 }
5843 return module;
5844 }
5845 fn wasm_execute_function(module: ptr<WasmModule>, func_offset: u64, locals: ptr<u64>, locals_count: u32) -> u64 {
5846 let mut pc = func_offset;
5847 let mut stack: [u64; 1024];
5848 let mut sp: u32 = 0;
5849 let code = (*module).code_base;
5850
5851 loop {
5852 let opcode = *(code as u64 + pc) as ptr<u8>;
5853 pc = pc + 1;
5854
5855 if *opcode == 0x0B {
5856 break;
5857 } else if *opcode == 0x20 {
5858 let local_idx = wasm_parse_leb128(code, &mut pc) as u32;
5859 if sp < 1024 && local_idx < locals_count {
5860 stack[sp as usize] = *(locals as u64 + local_idx as u64 * 8) as ptr<u64>;
5861 sp = sp + 1;
5862 }
5863 } else if *opcode == 0x21 {
5864 let local_idx = wasm_parse_leb128(code, &mut pc) as u32;
5865 if sp > 0 && local_idx < locals_count {
5866 sp = sp - 1;
5867 *(locals as u64 + local_idx as u64 * 8) as ptr<u64> = stack[sp as usize];
5868 }
5869 } else if *opcode == 0x41 {
5870 let val = wasm_parse_leb128(code, &mut pc);
5871 if sp < 1024 {
5872 stack[sp as usize] = val;
5873 sp = sp + 1;
5874 }
5875 } else if *opcode == 0x6A {
5876 if sp >= 2 {
5877 sp = sp - 1; let b = stack[sp as usize] as i32;
5878 sp = sp - 1; let a = stack[sp as usize] as i32;
5879 stack[sp as usize] = (a + b) as u32 as u64;
5880 sp = sp + 1;
5881 }
5882 } else if *opcode == 0x6B {
5883 if sp >= 2 {
5884 sp = sp - 1; let b = stack[sp as usize] as i32;
5885 sp = sp - 1; let a = stack[sp as usize] as i32;
5886 stack[sp as usize] = (a - b) as u32 as u64;
5887 sp = sp + 1;
5888 }
5889 } else if *opcode == 0x6C {
5890 if sp >= 2 {
5891 sp = sp - 1; let b = stack[sp as usize] as i32;
5892 sp = sp - 1; let a = stack[sp as usize] as i32;
5893 stack[sp as usize] = (a * b) as u32 as u64;
5894 sp = sp + 1;
5895 }
5896 }
5897 }
5898
5899 if sp > 0 {
5900 return stack[(sp - 1) as usize];
5901 }
5902 return 0;
5903 }
5904
5905 const DB_TYPE_STRING: u8 = 1;
5906 const DB_TYPE_LIST: u8 = 2;
5907 const DB_TYPE_INT: u8 = 3;
5908
5909 struct AegisDbEntry {
5910 key: [u8; 32],
5911 val_type: u8,
5912 val_int: u64,
5913 val_str: ptr<u8>,
5914 val_size: u64,
5915 next: ptr<AegisDbEntry>,
5916 }
5917
5918 let mut global_db_hash_table: [ptr<AegisDbEntry>; 1024];
5919 let mut db_lock: Spinlock;
5920
5921 fn db_hash_key(key: ptr<u8>) -> u32 {
5922 let mut hash: u32 = 5381;
5923 let mut i: u64 = 0;
5924 while *(key + i) != 0 && i < 31 {
5925 hash = ((hash << 5) + hash) + (*(key + i) as u32);
5926 i = i + 1;
5927 }
5928 return hash % 1024;
5929 }
5930
5931 fn db_init() {
5932 spin_init(&db_lock);
5933 for i in 0..1024 {
5934 global_db_hash_table[i] = 0 as ptr<AegisDbEntry>;
5935 }
5936 }
5937
5938 fn db_set_string(key: ptr<u8>, value: ptr<u8>) {
5939 spin_lock(&db_lock);
5940 let idx = db_hash_key(key);
5941
5942 let mut curr = global_db_hash_table[idx as usize];
5943 while curr != (0 as ptr<AegisDbEntry>) {
5944 if strncmp(&((*curr).key[0]) as ptr<u8>, key, 32) == 0 {
5945 if (*curr).val_str != (0 as ptr<u8>) && (*curr).val_size > 0 {
5946 let old_blocks = ((*curr).val_size + PAGE_SIZE - 1) / PAGE_SIZE;
5947 pmm_free_blocks((*curr).val_str as u64, old_blocks);
5948 }
5949 let len = strlen(value) + 1;
5950 let blocks = (len + PAGE_SIZE - 1) / PAGE_SIZE;
5951 (*curr).val_type = DB_TYPE_STRING;
5952 (*curr).val_size = len;
5953 (*curr).val_str = pmm_alloc_blocks(blocks) as ptr<u8>;
5954 memcpy((*curr).val_str, value, len);
5955 spin_unlock(&db_lock);
5956 return;
5957 }
5958 curr = (*curr).next;
5959 }
5960
5961 let new_entry = pmm_alloc_blocks(1) as ptr<AegisDbEntry>;
5962 memset(new_entry as ptr<u8>, 0, sizeof(AegisDbEntry) as u64);
5963
5964 let key_len = strlen(key);
5965 let copy_key_len = if key_len >= 31 { 31 } else { key_len };
5966 memcpy(&((*new_entry).key[0]) as ptr<u8>, key, copy_key_len);
5967 (*new_entry).key[copy_key_len as usize] = 0;
5968
5969 let len = strlen(value) + 1;
5970 let blocks = (len + PAGE_SIZE - 1) / PAGE_SIZE;
5971 (*new_entry).val_type = DB_TYPE_STRING;
5972 (*new_entry).val_size = len;
5973 (*new_entry).val_str = pmm_alloc_blocks(blocks) as ptr<u8>;
5974 memcpy((*new_entry).val_str, value, len);
5975
5976 (*new_entry).next = global_db_hash_table[idx as usize];
5977 global_db_hash_table[idx as usize] = new_entry;
5978 spin_unlock(&db_lock);
5979 }
5980
5981 fn db_get_string(key: ptr<u8>, out_buf: ptr<u8>, out_buf_max: u64) -> bool {
5982 spin_lock(&db_lock);
5983 let idx = db_hash_key(key);
5984 let mut curr = global_db_hash_table[idx as usize];
5985 while curr != (0 as ptr<AegisDbEntry>) {
5986 if strncmp(&((*curr).key[0]) as ptr<u8>, key, 32) == 0 && (*curr).val_type == DB_TYPE_STRING {
5987 if (*curr).val_str != (0 as ptr<u8>) {
5988 let copy_len = if (*curr).val_size < out_buf_max { (*curr).val_size } else { out_buf_max - 1 };
5989 memcpy(out_buf, (*curr).val_str, copy_len);
5990 *(out_buf + copy_len) = 0;
5991 spin_unlock(&db_lock);
5992 return true;
5993 }
5994 break;
5995 }
5996 curr = (*curr).next;
5997 }
5998 spin_unlock(&db_lock);
5999 return false;
6000 }
6001
6002 const PTRACE_TRACEME: u32 = 0;
6003 const PTRACE_PEEKTEXT: u32 = 1;
6004 const PTRACE_POKETEXT: u32 = 4;
6005 const PTRACE_CONT: u32 = 7;
6006 const PTRACE_SINGLESTEP: u32 = 9;
6007 const PTRACE_GETREGS: u32 = 12;
6008 const PTRACE_SETREGS: u32 = 13;
6009 const PTRACE_ATTACH: u32 = 16;
6010 const PTRACE_DETACH: u32 = 17;
6011
6012 struct PtraceState {
6013 is_traced: bool,
6014 tracer_pid: u64,
6015 stop_signal: u32,
6016 saved_opcode: u8,
6017 breakpoint_addr: u64,
6018 }
6019
6020 fn ptrace_attach(target_pid: u64, tracer_pid: u64) -> i32 {
6021 let mut curr = process_queue;
6022 while curr != (0 as ptr<ProcessControlBlock>) {
6023 if (*curr).pid == target_pid {
6024 let proc_ext = curr as ptr<ProcessControlBlockExt>;
6025 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
6026 if (*pstate).is_traced { return -1; }
6027 (*pstate).is_traced = true;
6028 (*pstate).tracer_pid = tracer_pid;
6029 signal_send(target_pid, 19);
6030 return 0;
6031 }
6032 curr = (*curr).next;
6033 }
6034 return -1;
6035 }
6036
6037 fn ptrace_getregs(target_pid: u64, out_ctx: ptr<CpuContext>) -> i32 {
6038 let mut curr = process_queue;
6039 while curr != (0 as ptr<ProcessControlBlock>) {
6040 if (*curr).pid == target_pid {
6041 let proc_ext = curr as ptr<ProcessControlBlockExt>;
6042 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
6043 if !(*pstate).is_traced { return -1; }
6044 memcpy(out_ctx as ptr<u8>, (*curr).context as ptr<u8>, sizeof(CpuContext) as u64);
6045 return 0;
6046 }
6047 curr = (*curr).next;
6048 }
6049 return -1;
6050 }
6051
6052 fn ptrace_set_breakpoint(target_pid: u64, addr: u64) -> i32 {
6053 let mut curr = process_queue;
6054 while curr != (0 as ptr<ProcessControlBlock>) {
6055 if (*curr).pid == target_pid {
6056 let proc_ext = curr as ptr<ProcessControlBlockExt>;
6057 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
6058 if !(*pstate).is_traced { return -1; }
6059
6060 let mut old_cr3: u64 = 0;
6061 asm { "mov %0, cr3" inout "=r"(old_cr3); }
6062 asm { "mov cr3, %0" in "r"((*curr).cr3_phys); }
6063
6064 (*pstate).saved_opcode = *(addr as ptr<u8>);
6065 *(addr as ptr<u8>) = 0xCC;
6066 (*pstate).breakpoint_addr = addr;
6067
6068 asm { "mov cr3, %0" in "r"(old_cr3); }
6069 return 0;
6070 }
6071 curr = (*curr).next;
6072 }
6073 return -1;
6074 }
6075
6076 fn exc_breakpoint_handler_adv() {
6077 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
6078 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
6079
6080 if (*pstate).is_traced {
6081 let rip = (*(*current_process).context).rip - 1;
6082
6083 if rip == (*pstate).breakpoint_addr {
6084 *(rip as ptr<u8>) = (*pstate).saved_opcode;
6085 (*(*current_process).context).rip = rip;
6086 (*pstate).breakpoint_addr = 0;
6087 }
6088
6089 (*current_process).state = 0;
6090 signal_send((*pstate).tracer_pid, 5);
6091 scheduler_tick();
6092 }
6093 }
6094
6095 const MSR_IA32_PERF_GLOBAL_CTRL: u32 = 0x38F;
6096 const MSR_IA32_PERFEVTSEL0: u32 = 0x186;
6097 const MSR_IA32_PERFEVTSEL1: u32 = 0x187;
6098 const MSR_IA32_PMC0: u32 = 0xC1;
6099 const MSR_IA32_PMC1: u32 = 0xC2;
6100 const MSR_IA32_FIXED_CTR_CTRL: u32 = 0x38D;
6101 const MSR_IA32_FIXED_CTR0: u32 = 0x309;
6102 const MSR_IA32_FIXED_CTR1: u32 = 0x30A;
6103 const MSR_IA32_FIXED_CTR2: u32 = 0x30B;
6104
6105 struct PmuStats {
6106 instructions: u64,
6107 core_cycles: u64,
6108 ref_cycles: u64,
6109 cache_misses: u64,
6110 branch_misses: u64,
6111 }
6112
6113 let mut global_pmu_stats: PmuStats;
6114
6115 fn pmu_init() {
6116 let mut cpuid_eax: u32 = 0;
6117 let mut cpuid_ebx: u32 = 0;
6118 let mut cpuid_ecx: u32 = 0;
6119 let mut cpuid_edx: u32 = 0;
6120 cpuid(0x0A, 0, &mut cpuid_eax, &mut cpuid_ebx, &mut cpuid_ecx, &mut cpuid_edx);
6121 let pmu_version = cpuid_eax & 0xFF;
6122 if pmu_version < 2 { return; }
6123
6124 wrmsr(MSR_IA32_PERF_GLOBAL_CTRL, 0);
6125 wrmsr(MSR_IA32_FIXED_CTR_CTRL, 0x333);
6126
6127 let evt_cache_miss: u64 = 0x00412E41;
6128 wrmsr(MSR_IA32_PERFEVTSEL0, evt_cache_miss);
6129
6130 let evt_branch_miss: u64 = 0x004100C5;
6131 wrmsr(MSR_IA32_PERFEVTSEL1, evt_branch_miss);
6132
6133 let enable_mask: u64 = (1u64 << 32) | (1u64 << 33) | (1u64 << 34) | 1u64 | 2u64;
6134 wrmsr(MSR_IA32_PERF_GLOBAL_CTRL, enable_mask);
6135 }
6136
6137 fn pmu_read_stats() {
6138 global_pmu_stats.instructions = rdmsr(MSR_IA32_FIXED_CTR0);
6139 global_pmu_stats.core_cycles = rdmsr(MSR_IA32_FIXED_CTR1);
6140 global_pmu_stats.ref_cycles = rdmsr(MSR_IA32_FIXED_CTR2);
6141 global_pmu_stats.cache_misses = rdmsr(MSR_IA32_PMC0);
6142 global_pmu_stats.branch_misses = rdmsr(MSR_IA32_PMC1);
6143 }
6144
6145 const EC_CMD_PORT: u16 = 0x66;
6146 const EC_DATA_PORT: u16 = 0x62;
6147 const EC_CMD_READ: u8 = 0x80;
6148 const EC_CMD_WRITE: u8 = 0x81;
6149 const EC_STAT_OBF: u8 = 0x01;
6150 const EC_STAT_IBF: u8 = 0x02;
6151
6152 fn acpi_ec_wait_write() -> bool {
6153 let mut timeout: u32 = 100000;
6154 while (inb(EC_CMD_PORT) & EC_STAT_IBF) != 0 {
6155 if timeout == 0 { return false; }
6156 cpu_pause();
6157 timeout = timeout - 1;
6158 }
6159 return true;
6160 }
6161
6162 fn acpi_ec_wait_read() -> bool {
6163 let mut timeout: u32 = 100000;
6164 while (inb(EC_CMD_PORT) & EC_STAT_OBF) == 0 {
6165 if timeout == 0 { return false; }
6166 cpu_pause();
6167 timeout = timeout - 1;
6168 }
6169 return true;
6170 }
6171
6172 fn acpi_ec_read(addr: u8) -> u8 {
6173 if !acpi_ec_wait_write() { return 0xFF; }
6174 outb(EC_CMD_PORT, EC_CMD_READ);
6175 if !acpi_ec_wait_write() { return 0xFF; }
6176 outb(EC_DATA_PORT, addr);
6177 if !acpi_ec_wait_read() { return 0xFF; }
6178 return inb(EC_DATA_PORT);
6179 }
6180
6181 fn acpi_ec_write(addr: u8, data: u8) {
6182 if !acpi_ec_wait_write() { return; }
6183 outb(EC_CMD_PORT, EC_CMD_WRITE);
6184 if !acpi_ec_wait_write() { return; }
6185 outb(EC_DATA_PORT, addr);
6186 if !acpi_ec_wait_write() { return; }
6187 outb(EC_DATA_PORT, data);
6188 }
6189
6190 struct BatteryState {
6191 is_present: bool,
6192 is_charging: bool,
6193 capacity_percent: u8,
6194 voltage_mv: u16,
6195 temperature_c: u8,
6196 }
6197
6198 let mut global_battery_state: BatteryState;
6199
6200 fn acpi_update_battery_state() {
6201 let bat_status = acpi_ec_read(0x10);
6202 global_battery_state.is_present = (bat_status & 0x01) != 0;
6203 global_battery_state.is_charging = (bat_status & 0x02) != 0;
6204
6205 if global_battery_state.is_present {
6206 let cap_high = acpi_ec_read(0x11);
6207 let cap_low = acpi_ec_read(0x12);
6208 let current_cap = ((cap_high as u16) << 8) | (cap_low as u16);
6209
6210 let max_high = acpi_ec_read(0x18);
6211 let max_low = acpi_ec_read(0x19);
6212 let mut max_cap = ((max_high as u16) << 8) | (max_low as u16);
6213 if max_cap == 0 { max_cap = 10000; }
6214
6215 global_battery_state.capacity_percent = ((current_cap as u32 * 100) / max_cap as u32) as u8;
6216 if global_battery_state.capacity_percent > 100 { global_battery_state.capacity_percent = 100; }
6217
6218 let volt_high = acpi_ec_read(0x13);
6219 let volt_low = acpi_ec_read(0x14);
6220 global_battery_state.voltage_mv = ((volt_high as u16) << 8) | (volt_low as u16);
6221
6222 let temp_raw = acpi_ec_read(0x15);
6223 if temp_raw >= 273 {
6224 global_battery_state.temperature_c = (temp_raw - 273) as u8;
6225 } else if temp_raw >= 27 {
6226 global_battery_state.temperature_c = temp_raw - 27;
6227 } else {
6228 global_battery_state.temperature_c = 0;
6229 }
6230 }
6231 }
6232
6233 struct UsbHubDescriptor {
6234 length: u8,
6235 descriptor_type: u8,
6236 num_ports: u8,
6237 hub_characteristics: u16,
6238 power_on_to_power_good: u8,
6239 hub_control_current: u8,
6240 device_removable: u8,
6241 port_power_ctrl_mask: u8,
6242 }
6243
6244 struct UsbHubPort {
6245 port_id: u8,
6246 is_connected: bool,
6247 is_enabled: bool,
6248 is_superspeed: bool,
6249 device_address: u8,
6250 }
6251
6252 struct UsbHubDevice {
6253 address: u8,
6254 num_ports: u8,
6255 ports: [UsbHubPort; 16],
6256 is_active: bool,
6257 }
6258
6259 let mut global_usb_hubs: [UsbHubDevice; 8];
6260 let mut usb_hub_count: u32 = 0;
6261
6262 fn usb_hub_init_device(device_addr: u8) {
6263 if usb_hub_count >= 8 { return; }
6264
6265 let hub = &mut global_usb_hubs[usb_hub_count as usize];
6266 (*hub).address = device_addr;
6267 (*hub).is_active = true;
6268
6269 let desc_buf = pmm_alloc_blocks(1) as ptr<UsbHubDescriptor>;
6270
6271 let mut setup: [u8; 8];
6272 setup[0] = 0xA0;
6273 setup[1] = 0x06;
6274 setup[2] = 0x00;
6275 setup[3] = 0x29;
6276 setup[4] = 0x00;
6277 setup[5] = 0x00;
6278 setup[6] = sizeof(UsbHubDescriptor) as u8;
6279 setup[7] = 0x00;
6280
6281 usb_control_transfer(device_addr, &setup[0] as ptr<u8>, desc_buf as ptr<u8>, sizeof(UsbHubDescriptor) as u16);
6282
6283 (*hub).num_ports = (*desc_buf).num_ports;
6284 if (*hub).num_ports > 16 { (*hub).num_ports = 16; }
6285
6286 for p in 0..(*hub).num_ports {
6287 (*hub).ports[p as usize].port_id = p + 1;
6288 (*hub).ports[p as usize].is_connected = false;
6289
6290 setup[0] = 0x23;
6291 setup[1] = 0x03;
6292 setup[2] = 8;
6293 setup[3] = 0;
6294 setup[4] = p + 1;
6295 setup[5] = 0;
6296 setup[6] = 0;
6297 setup[7] = 0;
6298 usb_control_transfer(device_addr, &setup[0] as ptr<u8>, 0 as ptr<u8>, 0);
6299 }
6300
6301 usb_hub_count = usb_hub_count + 1;
6302 pmm_free_blocks(desc_buf as u64, 1);
6303 }
6304
6305 fn usb_hub_poll_ports() {
6306 for i in 0..usb_hub_count {
6307 let hub = &mut global_usb_hubs[i as usize];
6308 if (*hub).is_active {
6309 for p in 0..(*hub).num_ports {
6310 let mut setup: [u8; 8];
6311 setup[0] = 0xA3;
6312 setup[1] = 0x00;
6313 setup[2] = 0x00;
6314 setup[3] = 0x00;
6315 setup[4] = (*hub).ports[p as usize].port_id;
6316 setup[5] = 0x00;
6317 setup[6] = 0x04;
6318 setup[7] = 0x00;
6319
6320 let mut status: u32 = 0;
6321 usb_control_transfer((*hub).address, &setup[0] as ptr<u8>, &mut status as ptr<u32> as ptr<u8>, 4);
6322
6323 let connected = (status & 0x0001) != 0;
6324 let connect_change = (status & 0x00010000) != 0;
6325
6326 if connect_change {
6327 setup[0] = 0x23;
6328 setup[1] = 0x01;
6329 setup[2] = 16;
6330 setup[3] = 0;
6331 setup[4] = (*hub).ports[p as usize].port_id;
6332 setup[5] = 0;
6333 setup[6] = 0;
6334 setup[7] = 0;
6335 usb_control_transfer((*hub).address, &setup[0] as ptr<u8>, 0 as ptr<u8>, 0);
6336
6337 if connected && !(*hub).ports[p as usize].is_connected {
6338 setup[0] = 0x23;
6339 setup[1] = 0x03;
6340 setup[2] = 4;
6341 setup[3] = 0;
6342 setup[4] = (*hub).ports[p as usize].port_id;
6343 setup[5] = 0;
6344 setup[6] = 0;
6345 setup[7] = 0;
6346 usb_control_transfer((*hub).address, &setup[0] as ptr<u8>, 0 as ptr<u8>, 0);
6347
6348 (*hub).ports[p as usize].is_connected = true;
6349 } else if !connected && (*hub).ports[p as usize].is_connected {
6350 (*hub).ports[p as usize].is_connected = false;
6351 (*hub).ports[p as usize].device_address = 0;
6352 }
6353 }
6354 }
6355 }
6356 }
6357 }
6358
6359 const SHADER_OP_NOP: u8 = 0;
6360 const SHADER_OP_MOV: u8 = 1;
6361 const SHADER_OP_ADD: u8 = 2;
6362 const SHADER_OP_MUL: u8 = 3;
6363 const SHADER_OP_DOT3: u8 = 4;
6364 const SHADER_OP_TEX: u8 = 5;
6365 const SHADER_OP_END: u8 = 255;
6366
6367 struct ShaderInstruction {
6368 opcode: u8,
6369 dest_reg: u8,
6370 src1_reg: u8,
6371 src2_reg: u8,
6372 }
6373
6374 struct GpuEuProgram {
6375 instructions: ptr<u32>,
6376 inst_count: u32,
6377 mem_blocks: u64,
6378 }
6379
6380 fn gpu_shader_compile(shader_src: ptr<ShaderInstruction>, count: u32) -> ptr<GpuEuProgram> {
6381 let prog = pmm_alloc_blocks(1) as ptr<GpuEuProgram>;
6382 let max_native_inst = count * 4;
6383 let mem_blocks = (max_native_inst as u64 * 4 + PAGE_SIZE - 1) / PAGE_SIZE;
6384 (*prog).instructions = pmm_alloc_blocks(mem_blocks) as ptr<u32>;
6385 (*prog).inst_count = 0;
6386 (*prog).mem_blocks = mem_blocks;
6387
6388 for i in 0..count {
6389 let inst = (shader_src as u64 + i as u64 * sizeof(ShaderInstruction) as u64) as ptr<ShaderInstruction>;
6390 let op = (*inst).opcode;
6391 let dst = (*inst).dest_reg;
6392 let s1 = (*inst).src1_reg;
6393 let s2 = (*inst).src2_reg;
6394
6395 let out_ptr = ((*prog).instructions as u64 + (*prog).inst_count as u64 * 4) as ptr<u32>;
6396
6397 if op == SHADER_OP_ADD {
6398 *out_ptr = 0x40000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6399 (*prog).inst_count = (*prog).inst_count + 1;
6400 } else if op == SHADER_OP_MUL {
6401 *out_ptr = 0x41000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6402 (*prog).inst_count = (*prog).inst_count + 1;
6403 } else if op == SHADER_OP_DOT3 {
6404 *out_ptr = 0x42000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6405 (*prog).inst_count = (*prog).inst_count + 1;
6406 } else if op == SHADER_OP_END {
6407 *out_ptr = 0xFFFFFFFF;
6408 (*prog).inst_count = (*prog).inst_count + 1;
6409 break;
6410 }
6411 }
6412 return prog;
6413 }
6414
6415 fn gpu_shader_bind(prog: ptr<GpuEuProgram>) {
6416 let virt_addr = (*prog).instructions as u64;
6417 let phys_addr = vmm_get_physical_address(virt_addr);
6418 intel_gpu_submit_cmd(0x71000000);
6419 intel_gpu_submit_cmd((phys_addr & 0xFFFFFFFF) as u32);
6420 intel_gpu_submit_cmd((phys_addr >> 32) as u32);
6421 intel_gpu_submit_cmd((*prog).inst_count * 4);
6422 }
6423
6424 fn chainload_mbr(drive_num: u8, partition_lba: u64) {
6425 let boot_sector = 0x7C00 as ptr<u8>;
6426 let phys_dest = vmm_get_physical_address(0x7C00);
6427
6428 ahci_read_sectors(global_raid_sys.disks[0].ahci_port, partition_lba, 1, phys_dest);
6429
6430 let signature = *(0x7DFE as ptr<u16>);
6431 if signature != 0xAA55 {
6432 shell_print_string("Chainload failed: Invalid MBR signature.\n" as ptr<u8>);
6433 return;
6434 }
6435
6436 cpu_cli();
6437 asm {
6438 "mov dl, %0" in "r"(drive_num);
6439 "mov si, 0x7C00";
6440 "jmp 0x0000:0x7C00";
6441 }
6442
6443
6444 cpu_cli();
6445
6446 asm {
6447 "mov edx, %0\n"
6448 "jmp 0x0000:0x7C00"
6449 in "%0" = drive_num as u32;
6450 }
6451 }
6452
6453 struct Tpm2CrbControlArea {
6454 req: u32,
6455 sts: u32,
6456 cancel: u32,
6457 start: u32,
6458 int_ctrl: u64,
6459 cmd_size: u32,
6460 cmd_addr_low: u32,
6461 cmd_addr_high: u32,
6462 rsp_size: u32,
6463 rsp_addr_low: u32,
6464 rsp_addr_high: u32,
6465 }
6466
6467 struct Tpm2CmdHeader {
6468 tag: u16,
6469 param_size: u32,
6470 cmd_code: u32,
6471 }
6472
6473 let mut tpm2_crb_base: u64 = 0;
6474 let mut tpm2_ctrl_area: ptr<Tpm2CrbControlArea> = 0 as ptr<Tpm2CrbControlArea>;
6475 let mut tpm2_cmd_buf: ptr<u8> = 0 as ptr<u8>;
6476 let mut tpm2_rsp_buf: ptr<u8> = 0 as ptr<u8>;
6477
6478 fn tpm2_init(acpi_tpm2_base: u64) -> bool {
6479 tpm2_crb_base = acpi_tpm2_base;
6480 tpm2_ctrl_area = (tpm2_crb_base + 0x40) as ptr<Tpm2CrbControlArea>;
6481
6482 (*tpm2_ctrl_area).req = 1;
6483 let mut timeout = 1000000;
6484 while ((*tpm2_ctrl_area).sts & 1) == 0 && timeout > 0 {
6485 cpu_pause();
6486 timeout = timeout - 1;
6487 }
6488 if timeout == 0 { return false; }
6489
6490 let cmd_phys = (((*tpm2_ctrl_area).cmd_addr_high as u64) << 32) | ((*tpm2_ctrl_area).cmd_addr_low as u64);
6491 let rsp_phys = (((*tpm2_ctrl_area).rsp_addr_high as u64) << 32) | ((*tpm2_ctrl_area).rsp_addr_low as u64);
6492
6493 if cmd_phys == 0 || rsp_phys == 0 { return false; }
6494
6495 tpm2_cmd_buf = vmm_map_io(cmd_phys, (*tpm2_ctrl_area).cmd_size as u64) as ptr<u8>;
6496 tpm2_rsp_buf = vmm_map_io(rsp_phys, (*tpm2_ctrl_area).rsp_size as u64) as ptr<u8>;
6497 return true;
6498 }
6499
6500 fn tpm2_send_command(cmd: ptr<u8>, size: u32) -> bool {
6501 if tpm2_ctrl_area == (0 as ptr<Tpm2CrbControlArea>) || tpm2_cmd_buf == (0 as ptr<u8>) { return false; }
6502 if size > (*tpm2_ctrl_area).cmd_size { return false; }
6503
6504 memcpy(tpm2_cmd_buf, cmd, size as u64);
6505 (*tpm2_ctrl_area).start = 1;
6506
6507 let mut timeout = 2000000;
6508 while (*tpm2_ctrl_area).start != 0 && timeout > 0 {
6509 cpu_pause();
6510 timeout = timeout - 1;
6511 }
6512 return timeout > 0;
6513 }
6514
6515 fn tpm2_get_random(bytes: u16, out_buf: ptr<u8>) -> bool {
6516 if bytes == 0 || bytes > 32 { return false; }
6517 let mut cmd: [u8; 12];
6518 let hdr = &mut cmd[0] as ptr<u8> as ptr<Tpm2CmdHeader>;
6519 (*hdr).tag = htons(0x8001);
6520 (*hdr).param_size = htonl(12);
6521 (*hdr).cmd_code = htonl(0x0000017B);
6522 cmd[10] = (bytes >> 8) as u8;
6523 cmd[11] = (bytes & 0xFF) as u8;
6524
6525 if !tpm2_send_command(&mut cmd[0] as ptr<u8>, 12) { return false; }
6526
6527 let rsp_tag = ntohs(*(tpm2_rsp_buf as ptr<u16>));
6528 let rsp_size = ntohl(*((tpm2_rsp_buf as u64 + 2) as ptr<u32>));
6529 let rsp_code = ntohl(*((tpm2_rsp_buf as u64 + 6) as ptr<u32>));
6530 if rsp_code != 0 || rsp_size < 12 { return false; }
6531
6532 let out_size = ntohs(*((tpm2_rsp_buf as u64 + 10) as ptr<u16>));
6533 let copy_size = if out_size < bytes { out_size } else { bytes };
6534 memcpy(out_buf, (tpm2_rsp_buf as u64 + 12) as ptr<u8>, copy_size as u64);
6535 return true;
6536 }
6537
6538 fn rotl32(v: u32, c: u32) -> u32 {
6539 return (v << c) | (v >> (32 - c));
6540 }
6541
6542 struct ChaCha20Ctx {
6543 state: [u32; 16],
6544 }
6545
6546 fn chacha20_init(ctx: ptr<ChaCha20Ctx>, key: ptr<u8>, nonce: ptr<u8>, counter: u32) {
6547 (*ctx).state[0] = 0x61707865;
6548 (*ctx).state[1] = 0x3320646e;
6549 (*ctx).state[2] = 0x79622d32;
6550 (*ctx).state[3] = 0x6b206574;
6551 for i in 0..8 {
6552 let p = (key as u64 + i as u64 * 4) as ptr<u8>;
6553 (*ctx).state[4 + i] = (*p as u32) | ((*(p as u64 + 1) as ptr<u8> as u32) << 8) | ((*(p as u64 + 2) as ptr<u8> as u32) << 16) | ((*(p as u64 + 3) as ptr<u8> as u32) << 24);
6554 }
6555 (*ctx).state[12] = counter;
6556 for i in 0..3 {
6557 let p = (nonce as u64 + i as u64 * 4) as ptr<u8>;
6558 (*ctx).state[13 + i] = (*p as u32) | ((*(p as u64 + 1) as ptr<u8> as u32) << 8) | ((*(p as u64 + 2) as ptr<u8> as u32) << 16) | ((*(p as u64 + 3) as ptr<u8> as u32) << 24);
6559 }
6560 }
6561
6562 fn chacha20_quarter_round(s: ptr<u32>, a: usize, b: usize, c: usize, d: usize) {
6563 let pa = (s as u64 + a as u64 * 4) as ptr<u32>;
6564 let pb = (s as u64 + b as u64 * 4) as ptr<u32>;
6565 let pc = (s as u64 + c as u64 * 4) as ptr<u32>;
6566 let pd = (s as u64 + d as u64 * 4) as ptr<u32>;
6567
6568 *pa = *pa + *pb; *pd = rotl32(*pd ^ *pa, 16);
6569 *pc = *pc + *pd; *pb = rotl32(*pb ^ *pc, 12);
6570 *pa = *pa + *pb; *pd = rotl32(*pd ^ *pa, 8);
6571 *pc = *pc + *pd; *pb = rotl32(*pb ^ *pc, 7);
6572 }
6573
6574 fn chacha20_block(ctx: ptr<ChaCha20Ctx>, out: ptr<u32>) {
6575 let mut working_state: [u32; 16];
6576 for i in 0..16 { working_state[i] = (*ctx).state[i]; }
6577
6578 let ws_ptr = &mut working_state[0] as ptr<u32>;
6579 for _ in 0..10 {
6580 chacha20_quarter_round(ws_ptr, 0, 4, 8, 12);
6581 chacha20_quarter_round(ws_ptr, 1, 5, 9, 13);
6582 chacha20_quarter_round(ws_ptr, 2, 6, 10, 14);
6583 chacha20_quarter_round(ws_ptr, 3, 7, 11, 15);
6584 chacha20_quarter_round(ws_ptr, 0, 5, 10, 15);
6585 chacha20_quarter_round(ws_ptr, 1, 6, 11, 12);
6586 chacha20_quarter_round(ws_ptr, 2, 7, 8, 13);
6587 chacha20_quarter_round(ws_ptr, 3, 4, 9, 14);
6588 }
6589
6590 for i in 0..16 {
6591 let val = (*ctx).state[i] + working_state[i];
6592 let p = (out as u64 + i as u64 * 4) as ptr<u8>;
6593 *p = (val & 0xFF) as u8;
6594 *(p as u64 + 1) as ptr<u8> = ((val >> 8) & 0xFF) as u8;
6595 *(p as u64 + 2) as ptr<u8> = ((val >> 16) & 0xFF) as u8;
6596 *(p as u64 + 3) as ptr<u8> = ((val >> 24) & 0xFF) as u8;
6597 }
6598 (*ctx).state[12] = (*ctx).state[12] + 1;
6599 }
6600
6601 fn chacha20_encrypt(ctx: ptr<ChaCha20Ctx>, data: ptr<u8>, len: u64) {
6602 let mut i: u64 = 0;
6603 let mut block: [u32; 16];
6604 let block_u8 = &mut block[0] as ptr<u32> as ptr<u8>;
6605 while i < len {
6606 chacha20_block(ctx, &mut block[0] as ptr<u32>);
6607 let mut chunk: u64 = 64;
6608 if len - i < 64 { chunk = len - i; }
6609 for j in 0..chunk {
6610 let p = (data as u64 + i + j) as ptr<u8>;
6611 *p = *p ^ *(block_u8 as u64 + j) as ptr<u8>;
6612 }
6613 i = i + 64;
6614 }
6615 }
6616
6617 struct AvSignature {
6618 id: u32,
6619 name: [u8; 32],
6620 pattern: [u8; 16],
6621 pattern_len: u64,
6622 is_active: bool,
6623 }
6624
6625 let mut global_av_signatures: [AvSignature; 1024];
6626 let mut av_sig_count: u32 = 0;
6627
6628 fn av_init() {
6629 for i in 0..1024 { global_av_signatures[i].is_active = false; }
6630 }
6631
6632 fn av_add_signature(name: ptr<u8>, pattern: ptr<u8>, len: u64) {
6633 if av_sig_count >= 1024 || len == 0 || len > 16 { return; }
6634 let sig = &mut global_av_signatures[av_sig_count as usize];
6635 (*sig).id = av_sig_count;
6636
6637 let name_len = strlen(name);
6638 let copy_len = if name_len >= 31 { 31 } else { name_len };
6639 memcpy(&mut (*sig).name[0] as ptr<u8>, name, copy_len);
6640 (*sig).name[copy_len as usize] = 0;
6641
6642 memcpy(&mut (*sig).pattern[0] as ptr<u8>, pattern, len);
6643 (*sig).pattern_len = len;
6644 (*sig).is_active = true;
6645 av_sig_count = av_sig_count + 1;
6646 }
6647
6648 fn av_scan_memory_region(start_addr: u64, length: u64) -> ptr<AvSignature> {
6649 let data = start_addr as ptr<u8>;
6650 for i in 0..av_sig_count {
6651 let sig = &global_av_signatures[i as usize];
6652 if (*sig).is_active && length >= (*sig).pattern_len {
6653 let scan_limit = length - (*sig).pattern_len;
6654 for j in 0..=scan_limit {
6655 let mut is_match = true;
6656 for k in 0..(*sig).pattern_len {
6657 if *(data as u64 + j + k) as ptr<u8> != (*sig).pattern[k as usize] {
6658 is_match = false;
6659 break;
6660 }
6661 }
6662 if is_match { return sig as ptr<AvSignature>; }
6663 }
6664 }
6665 }
6666 return 0 as ptr<AvSignature>;
6667 }
6668
6669 fn av_monitor_process(pid: u64) {
6670 let mut curr = process_queue;
6671 while curr != (0 as ptr<ProcessControlBlock>) {
6672 if (*curr).pid == pid {
6673 let proc_map = (*curr).memory_map as ptr<ProcessMemoryMap>;
6674 if proc_map == (0 as ptr<ProcessMemoryMap>) { return; }
6675 let mut vma = (*proc_map).vma_head;
6676 while vma != (0 as ptr<VmaNode>) {
6677 if ((*vma).flags & 4) != 0 && (*vma).end_vaddr > (*vma).start_vaddr {
6678 let sig = av_scan_memory_region((*vma).start_vaddr, (*vma).end_vaddr - (*vma).start_vaddr);
6679 if sig != (0 as ptr<AvSignature>) {
6680 shell_print_string("AEGIS-AV ALERT: Malicious code detected! PID: " as ptr<u8>);
6681 let mut buf: [u8; 16];
6682 itoa(pid as i32, 10, &mut buf[0] as ptr<u8>);
6683 shell_print_string(&buf[0] as ptr<u8>);
6684 shell_print_string(" Threat: " as ptr<u8>);
6685 shell_print_string(&((*sig).name[0]) as ptr<u8>);
6686 shell_print_char(10);
6687 signal_send(pid, 9);
6688 return;
6689 }
6690 }
6691 vma = (*vma).next;
6692 }
6693 break;
6694 }
6695 curr = (*curr).next;
6696 }
6697 }
6698
6699 struct CowBlock {
6700 logical_block: u64,
6701 physical_block: u64,
6702 ref_count: u32,
6703 next: ptr<CowBlock>,
6704 }
6705
6706 struct CowSnapshot {
6707 snap_id: u32,
6708 timestamp: u64,
6709 blocks: ptr<CowBlock>,
6710 next: ptr<CowSnapshot>,
6711 }
6712
6713 let mut global_cow_mapping: ptr<CowBlock> = 0 as ptr<CowBlock>;
6714 let mut global_snapshots: ptr<CowSnapshot> = 0 as ptr<CowSnapshot>;
6715 let mut cow_next_snap_id: u32 = 1;
6716
6717 fn cow_init() {
6718 global_cow_mapping = 0 as ptr<CowBlock>;
6719 global_snapshots = 0 as ptr<CowSnapshot>;
6720 }
6721
6722 fn cow_get_physical(logical: u64) -> u64 {
6723 let mut curr = global_cow_mapping;
6724 while curr != (0 as ptr<CowBlock>) {
6725 if (*curr).logical_block == logical { return (*curr).physical_block; }
6726 curr = (*curr).next;
6727 }
6728 return logical;
6729 }
6730
6731 fn cow_write_block(logical: u64, data_buf: u64) {
6732 let mut curr = global_cow_mapping;
6733 let mut target_node = 0 as ptr<CowBlock>;
6734
6735 while curr != (0 as ptr<CowBlock>) {
6736 if (*curr).logical_block == logical { target_node = curr; break; }
6737 curr = (*curr).next;
6738 }
6739
6740 if target_node != (0 as ptr<CowBlock>) && (*target_node).ref_count > 1 {
6741 (*target_node).ref_count = (*target_node).ref_count - 1;
6742 let new_phys = swap_alloc_slot() + 2000000;
6743
6744 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
6745 memset(new_node as ptr<u8>, 0, sizeof(CowBlock) as u64);
6746 (*new_node).logical_block = logical;
6747 (*new_node).physical_block = new_phys;
6748 (*new_node).ref_count = 1;
6749 (*new_node).next = global_cow_mapping;
6750 global_cow_mapping = new_node;
6751
6752 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, new_phys, 8, data_buf);
6753 } else if target_node != (0 as ptr<CowBlock>) {
6754 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, (*target_node).physical_block, 8, data_buf);
6755 } else {
6756 let new_phys = swap_alloc_slot() + 2000000;
6757 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
6758 memset(new_node as ptr<u8>, 0, sizeof(CowBlock) as u64);
6759 (*new_node).logical_block = logical;
6760 (*new_node).physical_block = new_phys;
6761 (*new_node).ref_count = 1;
6762 (*new_node).next = global_cow_mapping;
6763 global_cow_mapping = new_node;
6764
6765 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, new_phys, 8, data_buf);
6766 }
6767 }
6768
6769 fn cow_create_snapshot() -> u32 {
6770 let snap = pmm_alloc_blocks(1) as ptr<CowSnapshot>;
6771 memset(snap as ptr<u8>, 0, sizeof(CowSnapshot) as u64);
6772 (*snap).snap_id = cow_next_snap_id;
6773 cow_next_snap_id = cow_next_snap_id + 1;
6774 (*snap).timestamp = current_time_tick;
6775
6776 let mut curr_block = global_cow_mapping;
6777 while curr_block != (0 as ptr<CowBlock>) {
6778 (*curr_block).ref_count = (*curr_block).ref_count + 1;
6779
6780 let copy_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
6781 memcpy(copy_node as ptr<u8>, curr_block as ptr<u8>, sizeof(CowBlock) as u64);
6782 (*copy_node).next = (*snap).blocks;
6783 (*snap).blocks = copy_node;
6784
6785 curr_block = (*curr_block).next;
6786 }
6787
6788 (*snap).next = global_snapshots;
6789 global_snapshots = snap;
6790 return (*snap).snap_id;
6791 }
6792
6793 fn cow_rollback_snapshot(snap_id: u32) -> bool {
6794 let mut snap = global_snapshots;
6795 while snap != (0 as ptr<CowSnapshot>) {
6796 if (*snap).snap_id == snap_id {
6797 let mut old_mapping = global_cow_mapping;
6798 while old_mapping != (0 as ptr<CowBlock>) {
6799 let next = (*old_mapping).next;
6800 if (*old_mapping).ref_count <= 1 {
6801 swap_free_slot((*old_mapping).physical_block - 2000000);
6802 } else {
6803 (*old_mapping).ref_count = (*old_mapping).ref_count - 1;
6804 }
6805 pmm_free_blocks(old_mapping as u64, 1);
6806 old_mapping = next;
6807 }
6808
6809 global_cow_mapping = 0 as ptr<CowBlock>;
6810 let mut snap_block = (*snap).blocks;
6811 while snap_block != (0 as ptr<CowBlock>) {
6812 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
6813 memcpy(new_node as ptr<u8>, snap_block as ptr<u8>, sizeof(CowBlock) as u64);
6814 (*new_node).next = global_cow_mapping;
6815 global_cow_mapping = new_node;
6816 (*snap_block).ref_count = (*snap_block).ref_count + 1;
6817 snap_block = (*snap_block).next;
6818 }
6819 return true;
6820 }
6821 snap = (*snap).next;
6822 }
6823 return false;
6824 }
6825
6826 struct FacsHeader {
6827 signature: [u8; 4],
6828 length: u32,
6829 hardware_signature: u32,
6830 firmware_waking_vector: u32,
6831 global_lock: u32,
6832 flags: u32,
6833 x_firmware_waking_vector: u64,
6834 version: u8,
6835 reserved: [u8; 3],
6836 ospm_flags: u32,
6837 }
6838
6839 fn acpi_enter_s3_sleep() {
6840 if acpi_fadt == (0 as ptr<FADTHeader>) { return; }
6841
6842 let facs_addr = if (*acpi_fadt).x_firmware_ctrl != 0 {
6843 (*acpi_fadt).x_firmware_ctrl
6844 } else {
6845 (*acpi_fadt).firmware_ctrl as u64
6846 };
6847
6848 if facs_addr != 0 {
6849 let facs = facs_addr as ptr<FacsHeader>;
6850 (*facs).firmware_waking_vector = 0x8000;
6851 if (*facs).version >= 1 {
6852 (*facs).x_firmware_waking_vector = 0;
6853 }
6854 }
6855
6856 let pm1a = (*acpi_fadt).pm1a_control_block;
6857 let pm1b = (*acpi_fadt).pm1b_control_block;
6858 let (slp_typ_a, slp_typ_b) = acpi_get_sleep_type(3);
6859 let slp_en: u16 = 1 << 13;
6860
6861 cpu_cli();
6862 if pm1a != 0 { outw(pm1a as u16, ((slp_typ_a as u16) << 10) | slp_en); }
6863 if pm1b != 0 { outw(pm1b as u16, ((slp_typ_b as u16) << 10) | slp_en); }
6864
6865 loop { cpu_hlt(); }
6866 }
6867
6868 struct TlsRecordHeader {
6869 content_type: u8,
6870 version_major: u8,
6871 version_minor: u8,
6872 length: u16,
6873 }
6874
6875 struct TlsHandshakeHeader {
6876 msg_type: u8,
6877 length: [u8; 3],
6878 }
6879
6880 const TLS_TYPE_CHANGE_CIPHER_SPEC: u8 = 20;
6881 const TLS_TYPE_ALERT: u8 = 21;
6882 const TLS_TYPE_HANDSHAKE: u8 = 22;
6883 const TLS_TYPE_APPLICATION_DATA: u8 = 23;
6884 const TLS_HS_CLIENT_HELLO: u8 = 1;
6885 const TLS_HS_SERVER_HELLO: u8 = 2;
6886 const TLS_HS_CERTIFICATE: u8 = 11;
6887 const TLS_HS_SERVER_KEY_EXCHANGE: u8 = 12;
6888 const TLS_HS_SERVER_HELLO_DONE: u8 = 14;
6889 const TLS_HS_CLIENT_KEY_EXCHANGE: u8 = 16;
6890 const TLS_HS_FINISHED: u8 = 20;
6891
6892 struct TlsSession {
6893 sock: ptr<TcpSocket>,
6894 master_secret: [u8; 48],
6895 client_random: [u8; 32],
6896 server_random: [u8; 32],
6897 is_handshake_complete: bool,
6898 cipher_suite: u16,
6899 tx_sequence: u64,
6900 rx_sequence: u64,
6901 }
6902
6903 let mut global_tls_sessions: [TlsSession; 128];
6904 let mut tls_session_count: u32 = 0;
6905
6906 fn tls_init() {
6907 for i in 0..128 {
6908 global_tls_sessions[i].is_handshake_complete = false;
6909 global_tls_sessions[i].tx_sequence = 0;
6910 global_tls_sessions[i].rx_sequence = 0;
6911 }
6912 }
6913
6914 fn tls_send_client_hello(session: ptr<TlsSession>) {
6915 let buf = pmm_alloc_blocks(1) as ptr<u8>;
6916 let rec = buf as ptr<TlsRecordHeader>;
6917 (*rec).content_type = TLS_TYPE_HANDSHAKE;
6918 (*rec).version_major = 3;
6919 (*rec).version_minor = 3;
6920
6921 let hs = (buf as u64 + sizeof(TlsRecordHeader) as u64) as ptr<TlsHandshakeHeader>;
6922 (*hs).msg_type = TLS_HS_CLIENT_HELLO;
6923
6924 let hello_data = (buf as u64 + sizeof(TlsRecordHeader) as u64 + sizeof(TlsHandshakeHeader) as u64) as ptr<u8>;
6925 *hello_data = 3;
6926 *(hello_data as u64 + 1) as ptr<u8> = 3;
6927
6928 for i in 0..32 {
6929 (*session).client_random[i] = (rand_next() & 0xFF) as u8;
6930 *(hello_data as u64 + 2 + i as u64) as ptr<u8> = (*session).client_random[i];
6931 }
6932
6933 *(hello_data as u64 + 34) as ptr<u8> = 0;
6934
6935 let cs_len = (hello_data as u64 + 35) as ptr<u16>;
6936 *cs_len = htons(4);
6937
6938 let cs_1 = (hello_data as u64 + 37) as ptr<u16>;
6939 *cs_1 = htons(0xC02F);
6940
6941 let cs_2 = (hello_data as u64 + 39) as ptr<u16>;
6942 *cs_2 = htons(0xC02B);
6943
6944 *(hello_data as u64 + 41) as ptr<u8> = 1;
6945 *(hello_data as u64 + 42) as ptr<u8> = 0;
6946
6947 let hs_len: u32 = 43;
6948 (*hs).length[0] = 0;
6949 (*hs).length[1] = ((hs_len >> 8) & 0xFF) as u8;
6950 (*hs).length[2] = (hs_len & 0xFF) as u8;
6951
6952 let total_hs_size = sizeof(TlsHandshakeHeader) as u16 + hs_len as u16;
6953 (*rec).length = htons(total_hs_size);
6954
6955 let packet_size = sizeof(TlsRecordHeader) as u32 + total_hs_size as u32;
6956 tcp_send_segment((*session).sock, 0x0018, buf, packet_size as u16);
6957 pmm_free_blocks(buf as u64, 1);
6958 }
6959
6960 fn tls_connect(sock: ptr<TcpSocket>) -> ptr<TlsSession> {
6961 if tls_session_count >= 128 { return 0 as ptr<TlsSession>; }
6962 let session = &mut global_tls_sessions[tls_session_count as usize];
6963 tls_session_count = tls_session_count + 1;
6964
6965 (*session).sock = sock;
6966 (*session).is_handshake_complete = false;
6967 tls_send_client_hello(session);
6968
6969 return session as ptr<TlsSession>;
6970 }
6971
6972 struct LivePatchHeader {
6973 magic: u32,
6974 patch_version: u32,
6975 num_funcs: u32,
6976 }
6977
6978 struct LivePatchFunc {
6979 old_addr: u64,
6980 new_addr: u64,
6981 size: u32,
6982 }
6983
6984 fn livepatch_apply(patch_data: ptr<u8>) -> bool {
6985 let hdr = patch_data as ptr<LivePatchHeader>;
6986 if (*hdr).magic != 0x4B4C5058 { return false; }
6987
6988 let funcs = (patch_data as u64 + sizeof(LivePatchHeader) as u64) as ptr<LivePatchFunc>;
6989
6990 cpu_cli();
6991
6992 let mut cr0: u64 = 0;
6993 asm { "mov %0, cr0" inout "=r"(cr0); }
6994 let cr0_unprotected = cr0 & !(1u64 << 16);
6995 asm { "mov cr0, %0" in "r"(cr0_unprotected); }
6996
6997 for i in 0..(*hdr).num_funcs {
6998 let f = (funcs as u64 + i as u64 * sizeof(LivePatchFunc) as u64) as ptr<LivePatchFunc>;
6999 let target = (*f).old_addr as ptr<u8>;
7000 let dest = (*f).new_addr;
7001 let rel_offset = (dest as i64 - ((*f).old_addr as i64 + 5)) as i32;
7002
7003 *target = 0xE9;
7004 *((target as u64 + 1) as ptr<i32>) = rel_offset;
7005
7006 cpu_invlpg((*f).old_addr);
7007 }
7008
7009 asm { "mov cr0, %0" in "r"(cr0); }
7010 cpu_sti();
7011 return true;
7012 }
7013
7014 fn rsod_dump_registers(ctx: ptr<CpuContext>) {
7015 comp_draw_rect(comp_root_window, 0, 0, comp_width, comp_height, 0xAA0000);
7016
7017 (*global_shell).win = comp_root_window;
7018 (*global_shell).fg_color = 0xFFFFFF;
7019
7020 shell_print_string("====================================================\n" as ptr<u8>);
7021 shell_print_string(" AEGIS-X KERNEL PANIC - RED SCREEN OF DEATH \n" as ptr<u8>);
7022 shell_print_string("====================================================\n" as ptr<u8>);
7023 shell_print_string("A critical system error has occurred. System halted.\n\n" as ptr<u8>);
7024
7025 let mut buf: [u8; 32];
7026 shell_print_string("RIP: 0x" as ptr<u8>); utoa_hex((*ctx).rip, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7027 shell_print_string("RAX: 0x" as ptr<u8>); utoa_hex((*ctx).rax, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
7028 shell_print_string("RBX: 0x" as ptr<u8>); utoa_hex((*ctx).rbx, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7029 shell_print_string("RCX: 0x" as ptr<u8>); utoa_hex((*ctx).rcx, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
7030 shell_print_string("RDX: 0x" as ptr<u8>); utoa_hex((*ctx).rdx, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7031 shell_print_string("RSI: 0x" as ptr<u8>); utoa_hex((*ctx).rsi, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
7032 shell_print_string("RDI: 0x" as ptr<u8>); utoa_hex((*ctx).rdi, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7033 shell_print_string("RSP: 0x" as ptr<u8>); utoa_hex((*ctx).rsp, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
7034 shell_print_string("RBP: 0x" as ptr<u8>); utoa_hex((*ctx).rbp, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n\n" as ptr<u8>);
7035
7036 let mut cr2: u64 = 0;
7037 asm { "mov %0, cr2" inout "=r"(cr2); }
7038 shell_print_string("CR2 (Fault Addr): 0x" as ptr<u8>); utoa_hex(cr2, &mut buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7039
7040 shell_print_string("\nStack Trace:\n" as ptr<u8>);
7041 let mut rbp_val = (*ctx).rbp;
7042 for _ in 0..8 {
7043 if rbp_val < 0xFFFF800000000000 || (rbp_val & 7) != 0 { break; }
7044 let ret_addr = *((rbp_val + 8) as ptr<u64>);
7045 if ret_addr == 0 { break; }
7046 shell_print_string("[<0x" as ptr<u8>);
7047 utoa_hex(ret_addr, &mut buf[0] as ptr<u8>);
7048 shell_print_string(&buf[0] as ptr<u8>);
7049 shell_print_string(">]\n" as ptr<u8>);
7050 rbp_val = *(rbp_val as ptr<u64>);
7051 }
7052
7053 shell_print_string("\nPlease restart your computer. (System Halted)" as ptr<u8>);
7054 }
7055
7056 fn kernel_panic(ctx: ptr<CpuContext>) -> ! {
7057 cpu_cli();
7058 rsod_dump_registers(ctx);
7059 loop { cpu_hlt(); }
7060 }
7061
7062 fn exc_page_fault(ctx: ptr<CpuContext>) {
7063 let mut cr2: u64 = 0;
7064 asm { "mov %0, cr2" inout "=r"(cr2); }
7065 let err_code = (*ctx).err_code;
7066
7067 let is_handled = vmm_handle_page_fault(cr2, err_code);
7068 if !is_handled {
7069 kernel_panic(ctx);
7070 }
7071 }
7072
7073 fn syscall_dispatch(rax: u64, rdi: u64, rsi: u64, rdx: u64, r10: u64, r8: u64, r9: u64) -> u64 {
7074 if rax == 0 { return sys_read_wrap(rdi, rsi, rdx); }
7075 if rax == 1 { return sys_write_wrap(rdi, rsi, rdx); }
7076 if rax == 2 { return sys_open_wrap(rdi, rsi); }
7077 if rax == 3 { pmm_free_blocks(rdi, 1); return 0; }
7078 if rax == 9 { return sys_mmap(rdi, rsi, rdx, r10, r8, r9); }
7079 if rax == 59 { return execve_ring3(rdi as ptr<u8>, rsi as u32, rdx as u32) as u64; }
7080 if rax == 60 { (*current_process).state = 0; scheduler_tick(); return 0; }
7081 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); return 0; }
7082 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); return 0; }
7083 if rax == 200 { sha256_init(rdi as ptr<Sha256Ctx>); sha256_transform(rdi as ptr<Sha256Ctx>, rsi as ptr<u8>); return 0; }
7084 if rax == 300 { return ipc_send_message(rdi, rsi, rdx as u32, r10 as ptr<u8>, r8 as u32) as u64; }
7085 if rax == 301 { return ipc_receive_message(rdi, rsi as ptr<IpcMessage>) as u64; }
7086 if rax == 400 { return tcp_create_socket() as u64; }
7087 if rax == 401 { tcp_connect(rdi as ptr<TcpSocket>, *(rsi as ptr<Ipv4Addr>), rdx as u16); return 0; }
7088 if rax == 402 { tcp_send_segment(rdi as ptr<TcpSocket>, 0x0018, rsi as ptr<u8>, rdx as u16); return 0; }
7089 if rax == 500 { return shm_create(rdi as u32, rsi, rdx as u32, r10) as u64; }
7090 if rax == 501 { return shm_attach(rdi, rsi, rdx) as u64; }
7091 if rax == 600 { return ptrace_attach(rdi, rsi) as u64; }
7092 if rax == 700 { return display_srv_create_surface(rdi) as u64; }
7093 if rax == 800 { return tensor_create(rdi as u32, rsi as u32) as u64; }
7094 return 0xFFFFFFFFFFFFFFFF;
7095 }
7096
7097 fn syscall_handler_master() {
7098 let mut num: u64 = 0;
7099 let mut a1: u64 = 0;
7100 let mut a2: u64 = 0;
7101 let mut a3: u64 = 0;
7102 let mut a4: u64 = 0;
7103 let mut a5: u64 = 0;
7104 let mut a6: u64 = 0;
7105
7106 asm {
7107 "mov %0, rax\n"
7108 "mov %1, rdi\n"
7109 "mov %2, rsi\n"
7110 "mov %3, rdx\n"
7111 "mov %4, r10\n"
7112 "mov %5, r8\n"
7113 "mov %6, r9\n"
7114 inout "=r"(num), "=r"(a1), "=r"(a2), "=r"(a3), "=r"(a4), "=r"(a5), "=r"(a6);
7115 }
7116
7117 let res = syscall_dispatch(num, a1, a2, a3, a4, a5, a6);
7118
7119 asm {
7120 "mov rax, %0\n"
7121 in "r"(res);
7122 }
7123 }
7124
7125 const MULTIBOOT_MAGIC: u32 = 0x2BADB002;
7126
7127 struct MultibootMmapEntry {
7128 size: u32,
7129 base_addr: u64,
7130 length: u64,
7131 type_: u32,
7132 }
7133
7134 struct MultibootInfo {
7135 flags: u32,
7136 mem_lower: u32,
7137 mem_upper: u32,
7138 boot_device: u32,
7139 cmdline: u32,
7140 mods_count: u32,
7141 mods_addr: u32,
7142 syms: [u32; 4],
7143 mmap_length: u32,
7144 mmap_addr: u32,
7145 drives_length: u32,
7146 drives_addr: u32,
7147 config_table: u32,
7148 boot_loader_name: u32,
7149 apm_table: u32,
7150 vbe_control_info: u32,
7151 vbe_mode_info: u32,
7152 vbe_mode: u16,
7153 vbe_interface_seg: u16,
7154 vbe_interface_off: u16,
7155 vbe_interface_len: u16,
7156 framebuffer_addr: u64,
7157 framebuffer_pitch: u32,
7158 framebuffer_width: u32,
7159 framebuffer_height: u32,
7160 framebuffer_bpp: u8,
7161 framebuffer_type: u8,
7162 }
7163
7164 #[no_mangle]
7165 pub fn kmain(magic: u32, mb_info: ptr<MultibootInfo>) -> ! {
7166 cpu_cli();
7167
7168 if magic != MULTIBOOT_MAGIC || mb_info == (0 as ptr<MultibootInfo>) {
7169 loop { cpu_hlt(); }
7170 }
7171
7172 init_gdt_smp();
7173 init_idt_smp();
7174
7175 let mut total_mem_bytes: u64 = 0;
7176 if ((*mb_info).flags & 0x0040) != 0 && (*mb_info).mmap_length > 0 {
7177 let mut mmap_curr = (*mb_info).mmap_addr as u64;
7178 let mmap_end = mmap_curr + (*mb_info).mmap_length as u64;
7179 while mmap_curr < mmap_end {
7180 let entry = mmap_curr as ptr<MultibootMmapEntry>;
7181 if (*entry).type_ == 1 {
7182 let end_addr = (*entry).base_addr + (*entry).length;
7183 if end_addr > total_mem_bytes { total_mem_bytes = end_addr; }
7184 }
7185 mmap_curr = mmap_curr + (*entry).size as u64 + 4;
7186 }
7187 }
7188 if total_mem_bytes == 0 && ((*mb_info).flags & 0x0001) != 0 {
7189 total_mem_bytes = ((*mb_info).mem_lower as u64 + (*mb_info).mem_upper as u64) * 1024;
7190 }
7191
7192 pmm_init(total_mem_bytes);
7193 vmm_init();
7194 acpi_init();
7195
7196 smp_init_all();
7197 smp_balancer_init();
7198
7199 let w = (*mb_info).framebuffer_width;
7200 let h = (*mb_info).framebuffer_height;
7201 let fb_base = (*mb_info).framebuffer_addr;
7202 if fb_base != 0 && w > 0 && h > 0 {
7203 comp_init(fb_base, w, h);
7204 vt_init();
7205 render_init_3d(w, h);
7206 }
7207
7208 pcie_init();
7209
7210 if global_ahci_hba != (0 as ptr<AHCIHBARegs>) {
7211 raid_init_system();
7212 for i in 0..32 {
7213 let port = &mut (*global_ahci_hba).ports[i as usize] as ptr<AHCIPortRegs>;
7214 if ((*port).ssts & 0x0F) == 3 {
7215 raid_add_disk(port, 100000000);
7216 }
7217 }
7218 }
7219
7220 vfs_init_system();
7221 if global_raid_sys.disk_count > 0 {
7222 ext2_init(0);
7223 jbd2_init(2000000, 2100000);
7224 }
7225 cow_init();
7226
7227 if (*mb_info).mods_count > 0 && (*mb_info).mods_addr != 0 {
7228 let mod_entry = (*mb_info).mods_addr as ptr<u32>;
7229 let initramfs_start = *mod_entry;
7230 let initramfs_end = *(mod_entry as u64 + 4) as ptr<u32>;
7231 if *initramfs_end > initramfs_start {
7232 tar_extract_initramfs(initramfs_start as u64, (*initramfs_end - initramfs_start) as u64);
7233 }
7234 }
7235
7236 loopback_init();
7237 fw_init();
7238 nat_init();
7239 tls_init();
7240
7241 auth_init_system();
7242 registry_init();
7243 db_init();
7244 av_init();
7245
7246 pmu_init();
7247 acpi_update_battery_state();
7248 vmx_init();
7249
7250 let shell_pid = execve_ring3("/bin/aegis_shell" as ptr<u8>, 0, 0);
7251 if shell_pid == 0 {
7252 let proc = create_process(shell_task as u64, true);
7253 }
7254
7255 let http_proc = create_process(http_server_task as u64, true);
7256 init_set_runlevel(3);
7257
7258 cpu_sti();
7259
7260 loop {
7261 scheduler_tick();
7262 smp_balance_load();
7263 display_srv_composite();
7264 usb_hub_poll_ports();
7265 cpu_pause();
7266 }
7267 }
7268
7269 struct YbgTransaction {
7270 sender_pubkey: [u8; 64],
7271 receiver_pubkey: [u8; 64],
7272 amount: u64,
7273 signature: [u8; 64],
7274 timestamp: u64,
7275 }
7276
7277 struct YbgBlockHeader {
7278 index: u64,
7279 prev_hash: [u8; 32],
7280 merkle_root: [u8; 32],
7281 timestamp: u64,
7282 difficulty: u32,
7283 nonce: u64,
7284 }
7285
7286 struct YbgBlock {
7287 header: YbgBlockHeader,
7288 transactions: ptr<YbgTransaction>,
7289 tx_count: u32,
7290 block_hash: [u8; 32],
7291 next: ptr<YbgBlock>,
7292 }
7293
7294 let mut blockchain_head: ptr<YbgBlock> = 0 as ptr<YbgBlock>;
7295 let mut current_difficulty: u32 = 4;
7296
7297 fn ybg_chain_init() {
7298 blockchain_head = pmm_alloc_blocks(1) as ptr<YbgBlock>;
7299 memset(blockchain_head as ptr<u8>, 0, sizeof(YbgBlock) as u64);
7300 (*blockchain_head).header.index = 0;
7301 memcpy(&mut (*blockchain_head).header.prev_hash[0] as ptr<u8>, "YBG13_GENESIS_BLOCK_00000000000" as ptr<u8>, 31);
7302 (*blockchain_head).header.timestamp = current_time_tick;
7303 (*blockchain_head).header.difficulty = current_difficulty;
7304 (*blockchain_head).header.nonce = 0;
7305 (*blockchain_head).tx_count = 0;
7306 }
7307
7308 fn ybg_check_hash_difficulty(hash: ptr<u8>, difficulty: u32) -> bool {
7309 let mut zero_nibbles: u32 = 0;
7310 for i in 0..32 {
7311 let byte = *(hash as u64 + i as u64) as ptr<u8>;
7312 if *byte == 0 {
7313 zero_nibbles = zero_nibbles + 2;
7314 } else if (*byte & 0xF0) == 0 {
7315 zero_nibbles = zero_nibbles + 1;
7316 break;
7317 } else {
7318 break;
7319 }
7320 if zero_nibbles >= difficulty { return true; }
7321 }
7322 return zero_nibbles >= difficulty;
7323 }
7324
7325 fn sha256_full(data: ptr<u8>, len: u64, out_hash: ptr<u8>) {
7326 let mut ctx: Sha256Ctx;
7327 sha256_init(&mut ctx);
7328 let mut remaining = len;
7329 let mut curr = data as u64;
7330 while remaining >= 64 {
7331 sha256_transform(&mut ctx, curr as ptr<u8>);
7332 curr = curr + 64;
7333 remaining = remaining - 64;
7334 }
7335 let mut last_block: [u8; 64];
7336 memset(&mut last_block[0] as ptr<u8>, 0, 64);
7337 if remaining > 0 {
7338 memcpy(&mut last_block[0] as ptr<u8>, curr as ptr<u8>, remaining);
7339 }
7340 last_block[remaining as usize] = 0x80;
7341 if remaining >= 56 {
7342 sha256_transform(&mut ctx, &mut last_block[0] as ptr<u8>);
7343 memset(&mut last_block[0] as ptr<u8>, 0, 64);
7344 }
7345 let bit_len = len * 8;
7346 for b in 0..8 {
7347 last_block[(63 - b) as usize] = ((bit_len >> (b * 8)) & 0xFF) as u8;
7348 }
7349 sha256_transform(&mut ctx, &mut last_block[0] as ptr<u8>);
7350 for i in 0..8 {
7351 let val = ctx.state[i];
7352 let p = (out_hash as u64 + i as u64 * 4) as ptr<u8>;
7353 *p = ((val >> 24) & 0xFF) as u8;
7354 *(p as u64 + 1) as ptr<u8> = ((val >> 16) & 0xFF) as u8;
7355 *(p as u64 + 2) as ptr<u8> = ((val >> 8) & 0xFF) as u8;
7356 *(p as u64 + 3) as ptr<u8> = (val & 0xFF) as u8;
7357 }
7358 }
7359
7360 fn ybg_mine_block(target_block: ptr<YbgBlock>) {
7361 let mut attempt_hash: [u8; 32];
7362 shell_print_string("CHT-Miner: YBG13 Token kazimi basladi...\n" as ptr<u8>);
7363
7364 loop {
7365 sha256_full(
7366 &mut (*target_block).header as ptr<YbgBlockHeader> as ptr<u8>,
7367 sizeof(YbgBlockHeader) as u64,
7368 &mut attempt_hash[0] as ptr<u8>
7369 );
7370
7371 if ybg_check_hash_difficulty(&mut attempt_hash[0] as ptr<u8>, (*target_block).header.difficulty) {
7372 memcpy(&mut (*target_block).block_hash[0] as ptr<u8>, &mut attempt_hash[0] as ptr<u8>, 32);
7373 shell_print_string("CHT-Miner: Blok Bulundu! Nonce: " as ptr<u8>);
7374 let mut buf: [u8; 32];
7375 itoa((*target_block).header.nonce as i32, 10, &mut buf[0] as ptr<u8>);
7376 shell_print_string(&buf[0] as ptr<u8>);
7377 shell_print_string("\n" as ptr<u8>);
7378 break;
7379 }
7380
7381 (*target_block).header.nonce = (*target_block).header.nonce + 1;
7382 if ((*target_block).header.nonce % 10000) == 0 {
7383 scheduler_tick();
7384 }
7385 }
7386 }
7387
7388 struct ChtScanTarget {
7389 ip: Ipv4Addr,
7390 port_start: u16,
7391 port_end: u16,
7392 open_ports: [u16; 1024],
7393 open_count: u32,
7394 }
7395
7396 fn cht_stealth_syn_scan(target: ptr<ChtScanTarget>) {
7397 shell_print_string("CHT-Sec: Stealth SYN Scan baslatiliyor...\n" as ptr<u8>);
7398
7399 let sock = tcp_create_socket();
7400 if sock == (0 as ptr<TcpSocket>) { return; }
7401
7402 (*target).open_count = 0;
7403
7404 for port in (*target).port_start..=(*target).port_end {
7405 tcp_bind(sock, 45000 + (port % 10000));
7406 (*sock).remote_ip = (*target).ip;
7407 (*sock).remote_port = port;
7408 (*sock).seq_num = hw_rdrand_64() as u32;
7409 (*sock).state = TCP_STATE_SYN_SENT;
7410
7411 tcp_send_segment(sock, 0x0002, 0 as ptr<u8>, 0);
7412
7413 let mut timeout: u32 = 5000;
7414 let mut port_open = false;
7415
7416 while timeout > 0 {
7417 if (*sock).state == TCP_STATE_SYN_RCVD || (*sock).state == TCP_STATE_ESTABLISHED {
7418 port_open = true;
7419 break;
7420 }
7421 if (*sock).state == TCP_STATE_CLOSED { break; }
7422 timeout = timeout - 1;
7423 cpu_pause();
7424 }
7425
7426 if port_open {
7427 if (*target).open_count < 1024 {
7428 (*target).open_ports[(*target).open_count as usize] = port;
7429 (*target).open_count = (*target).open_count + 1;
7430
7431 shell_print_string("CHT-Sec: Port Acik -> " as ptr<u8>);
7432 let mut pbuf: [u8; 16];
7433 itoa(port as i32, 10, &mut pbuf[0] as ptr<u8>);
7434 shell_print_string(&pbuf[0] as ptr<u8>);
7435 shell_print_string("\n" as ptr<u8>);
7436 }
7437 tcp_send_segment(sock, 0x0004, 0 as ptr<u8>, 0);
7438 }
7439
7440 (*sock).state = TCP_STATE_CLOSED;
7441 (*sock).rx_head = 0;
7442 (*sock).rx_tail = 0;
7443 }
7444
7445 tcp_close(sock);
7446 shell_print_string("CHT-Sec: Tarama Tamamlandi.\n" as ptr<u8>);
7447 }
7448
7449 struct UavTelemetryPacket {
7450 magic: u32,
7451 device_id: u8,
7452 timestamp: u64,
7453 accel_x: f32,
7454 accel_y: f32,
7455 accel_z: f32,
7456 gyro_x: f32,
7457 gyro_y: f32,
7458 gyro_z: f32,
7459 depth_pressure: f32,
7460 motor_rpm: [u16; 4],
7461 battery_voltage: f32,
7462 checksum: u16,
7463 }
7464
7465 let mut uav_last_telemetry: UavTelemetryPacket;
7466
7467 fn uav_parse_telemetry(udp_payload: ptr<u8>, length: u32) {
7468 if length != sizeof(UavTelemetryPacket) as u32 || udp_payload == (0 as ptr<u8>) { return; }
7469
7470 let pkt = udp_payload as ptr<UavTelemetryPacket>;
7471 if (*pkt).magic != 0x414E4B41 { return; }
7472
7473 let mut csum: u32 = 0;
7474 let ptr16 = udp_payload as ptr<u16>;
7475 let words = (length - 2) / 2;
7476 for i in 0..words {
7477 csum = csum + ntohs(*(ptr16 as u64 + i as u64 * 2) as ptr<u16>) as u32;
7478 }
7479 while (csum >> 16) != 0 {
7480 csum = (csum & 0xFFFF) + (csum >> 16);
7481 }
7482 let calc_csum = (!csum) as u16;
7483
7484 if calc_csum == ntohs((*pkt).checksum) {
7485 memcpy(&mut uav_last_telemetry as ptr<UavTelemetryPacket> as ptr<u8>, udp_payload, length as u64);
7486 }
7487 }
7488
7489 const TK_EOF: u8 = 0;
7490 const TK_IDENTIFIER: u8 = 1;
7491 const TK_NUMBER: u8 = 2;
7492 const TK_PLUS: u8 = 3;
7493 const TK_MINUS: u8 = 4;
7494 const TK_ASSIGN: u8 = 5;
7495 const TK_PRINT: u8 = 6;
7496 const TK_SEMI: u8 = 7;
7497
7498 struct ScriptToken {
7499 type_: u8,
7500 value_int: i64,
7501 name: [u8; 32],
7502 }
7503
7504 struct ScriptLexer {
7505 src: ptr<u8>,
7506 pos: u32,
7507 len: u32,
7508 }
7509
7510 fn script_is_alpha(c: u8) -> bool {
7511 return (c >= 'a' as u8 && c <= 'z' as u8) || (c >= 'A' as u8 && c <= 'Z' as u8) || c == '_' as u8;
7512 }
7513
7514 fn script_is_digit(c: u8) -> bool {
7515 return c >= '0' as u8 && c <= '9' as u8;
7516 }
7517
7518 fn script_next_token(lex: ptr<ScriptLexer>, out_tok: ptr<ScriptToken>) {
7519 while (*lex).pos < (*lex).len {
7520 let c = *((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>;
7521 if c == ' ' as u8 || c == 10 || c == 13 || c == 9 {
7522 (*lex).pos = (*lex).pos + 1;
7523 continue;
7524 }
7525
7526 if script_is_digit(c) {
7527 (*out_tok).type_ = TK_NUMBER;
7528 (*out_tok).value_int = 0;
7529 while (*lex).pos < (*lex).len && script_is_digit(*((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>) {
7530 (*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;
7531 (*lex).pos = (*lex).pos + 1;
7532 }
7533 return;
7534 }
7535
7536 if script_is_alpha(c) {
7537 let mut i: u32 = 0;
7538 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 {
7539 (*out_tok).name[i as usize] = *((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>;
7540 (*lex).pos = (*lex).pos + 1;
7541 i = i + 1;
7542 }
7543 (*out_tok).name[i as usize] = 0;
7544
7545 if strcmp(&mut (*out_tok).name[0] as ptr<u8>, "print" as ptr<u8>) == 0 {
7546 (*out_tok).type_ = TK_PRINT;
7547 } else {
7548 (*out_tok).type_ = TK_IDENTIFIER;
7549 }
7550 return;
7551 }
7552
7553 if c == '+' as u8 { (*out_tok).type_ = TK_PLUS; (*lex).pos = (*lex).pos + 1; return; }
7554 if c == '-' as u8 { (*out_tok).type_ = TK_MINUS; (*lex).pos = (*lex).pos + 1; return; }
7555 if c == '=' as u8 { (*out_tok).type_ = TK_ASSIGN; (*lex).pos = (*lex).pos + 1; return; }
7556 if c == ';' as u8 { (*out_tok).type_ = TK_SEMI; (*lex).pos = (*lex).pos + 1; return; }
7557
7558 (*lex).pos = (*lex).pos + 1;
7559 }
7560 (*out_tok).type_ = TK_EOF;
7561 }
7562
7563 struct ScriptVar {
7564 name: [u8; 32],
7565 value: i64,
7566 is_active: bool,
7567 }
7568
7569 let mut global_script_env: [ScriptVar; 64];
7570
7571 fn script_set_var(name: ptr<u8>, val: i64) {
7572 for i in 0..64 {
7573 if global_script_env[i].is_active && strncmp(&mut (global_script_env[i].name[0]) as ptr<u8>, name, 32) == 0 {
7574 global_script_env[i].value = val;
7575 return;
7576 }
7577 }
7578 for i in 0..64 {
7579 if !global_script_env[i].is_active {
7580 let len = strlen(name);
7581 let copy_len = if len >= 31 { 31 } else { len };
7582 memcpy(&mut (global_script_env[i].name[0]) as ptr<u8>, name, copy_len);
7583 global_script_env[i].name[copy_len as usize] = 0;
7584 global_script_env[i].value = val;
7585 global_script_env[i].is_active = true;
7586 return;
7587 }
7588 }
7589 }
7590
7591 fn script_get_var(name: ptr<u8>) -> i64 {
7592 for i in 0..64 {
7593 if global_script_env[i].is_active && strncmp(&mut (global_script_env[i].name[0]) as ptr<u8>, name, 32) == 0 {
7594 return global_script_env[i].value;
7595 }
7596 }
7597 return 0;
7598 }
7599
7600 fn aegis_script_run(source_code: ptr<u8>) {
7601 if source_code == (0 as ptr<u8>) { return; }
7602 let mut lex: ScriptLexer;
7603 lex.src = source_code;
7604 lex.pos = 0;
7605 lex.len = strlen(source_code) as u32;
7606
7607 for i in 0..64 { global_script_env[i].is_active = false; }
7608
7609 let mut tok: ScriptToken;
7610 script_next_token(&mut lex, &mut tok);
7611
7612 while tok.type_ != TK_EOF {
7613 if tok.type_ == TK_IDENTIFIER {
7614 let mut var_name: [u8; 32];
7615 memcpy(&mut var_name[0] as ptr<u8>, &mut tok.name[0] as ptr<u8>, 32);
7616 script_next_token(&mut lex, &mut tok);
7617 if tok.type_ == TK_ASSIGN {
7618 script_next_token(&mut lex, &mut tok);
7619 let mut val: i64 = 0;
7620 if tok.type_ == TK_NUMBER {
7621 val = tok.value_int;
7622 } else if tok.type_ == TK_IDENTIFIER {
7623 val = script_get_var(&mut tok.name[0] as ptr<u8>);
7624 }
7625 script_next_token(&mut lex, &mut tok);
7626 while tok.type_ == TK_PLUS || tok.type_ == TK_MINUS {
7627 let is_add = tok.type_ == TK_PLUS;
7628 script_next_token(&mut lex, &mut tok);
7629 let mut term: i64 = 0;
7630 if tok.type_ == TK_NUMBER {
7631 term = tok.value_int;
7632 } else if tok.type_ == TK_IDENTIFIER {
7633 term = script_get_var(&mut tok.name[0] as ptr<u8>);
7634 }
7635 if is_add { val = val + term; } else { val = val - term; }
7636 script_next_token(&mut lex, &mut tok);
7637 }
7638 script_set_var(&mut var_name[0] as ptr<u8>, val);
7639 }
7640 } else if tok.type_ == TK_PRINT {
7641 script_next_token(&mut lex, &mut tok);
7642 let mut val: i64 = 0;
7643 if tok.type_ == TK_NUMBER {
7644 val = tok.value_int;
7645 } else if tok.type_ == TK_IDENTIFIER {
7646 val = script_get_var(&mut tok.name[0] as ptr<u8>);
7647 }
7648 script_next_token(&mut lex, &mut tok);
7649 while tok.type_ == TK_PLUS || tok.type_ == TK_MINUS {
7650 let is_add = tok.type_ == TK_PLUS;
7651 script_next_token(&mut lex, &mut tok);
7652 let mut term: i64 = 0;
7653 if tok.type_ == TK_NUMBER {
7654 term = tok.value_int;
7655 } else if tok.type_ == TK_IDENTIFIER {
7656 term = script_get_var(&mut tok.name[0] as ptr<u8>);
7657 }
7658 if is_add { val = val + term; } else { val = val - term; }
7659 script_next_token(&mut lex, &mut tok);
7660 }
7661 shell_print_string("Aegis-Script Out: " as ptr<u8>);
7662 let mut buf: [u8; 32];
7663 itoa(val as i32, 10, &mut buf[0] as ptr<u8>);
7664 shell_print_string(&buf[0] as ptr<u8>);
7665 shell_print_string("\n" as ptr<u8>);
7666 } else {
7667 script_next_token(&mut lex, &mut tok);
7668 }
7669 }
7670 }
7671
7672 const MB_MAGIC: u32 = 0x1BADB002;
7673 const MB_FLAGS: u32 = 0x00000003;
7674 const MB_CKSUM: u32 = -(MB_MAGIC + MB_FLAGS);
7675
7676 struct Multiboot { magic: u32, flags: u32, checksum: u32 }
7677
7678 #[link_section = ".multiboot"]
7679 const HEADER: Multiboot = Multiboot { magic: MB_MAGIC, flags: MB_FLAGS, checksum: MB_CKSUM };
7680
7681 fn outb(p: u16, d: u8) { asm { "out dx, al" in "dx"(p), "al"(d); } }
7682 fn outw(p: u16, d: u16) { asm { "out dx, ax" in "dx"(p), "ax"(d); } }
7683 fn outl(p: u16, d: u32) { asm { "out dx, eax" in "dx"(p), "eax"(d); } }
7684
7685 fn inb(p: u16) -> u8 {
7686 let mut d: u8 = 0;
7687 asm { "in al, dx" in "dx"(p), inout "=al"(d); }
7688 return d;
7689 }
7690
7691 fn inw(p: u16) -> u16 {
7692 let mut d: u16 = 0;
7693 asm { "in ax, dx" in "dx"(p), inout "=ax"(d); }
7694 return d;
7695 }
7696
7697 fn inl(p: u16) -> u32 {
7698 let mut d: u32 = 0;
7699 asm { "in eax, dx" in "dx"(p), inout "=eax"(d); }
7700 return d;
7701 }
7702
7703 struct CpuContext {
7704 r15: u64, r14: u64, r13: u64, r12: u64,
7705 r11: u64, r10: u64, r9: u64, r8: u64,
7706 rbp: u64, rdi: u64, rsi: u64, rdx: u64,
7707 rcx: u64, rbx: u64, rax: u64,
7708 rip: u64, cs: u64, rflags: u64, rsp: u64, ss: u64,
7709 }
7710
7711 struct ProcessControlBlock {
7712 pid: u64,
7713 state: u8,
7714 cr3_phys: u64,
7715 context: ptr<CpuContext>,
7716 time_slice: u64,
7717 privilege_level: u8,
7718 next: ptr<ProcessControlBlock>,
7719 }
7720
7721 let mut current_process: ptr<ProcessControlBlock> = 0 as ptr<ProcessControlBlock>;
7722 let mut process_queue: ptr<ProcessControlBlock> = 0 as ptr<ProcessControlBlock>;
7723
7724 fn sched() {
7725 if process_queue == (0 as ptr<ProcessControlBlock>) { return; }
7726
7727 let start_proc = if current_process != (0 as ptr<ProcessControlBlock>) {
7728 (*current_process).next
7729 } else {
7730 process_queue
7731 };
7732
7733 let mut curr = if start_proc != (0 as ptr<ProcessControlBlock>) { start_proc } else { process_queue };
7734 let mut loop_count: u32 = 0;
7735
7736 while (*curr).state != 1 && loop_count < 1024 {
7737 curr = (*curr).next;
7738 if curr == (0 as ptr<ProcessControlBlock>) {
7739 curr = process_queue;
7740 }
7741 loop_count = loop_count + 1;
7742 }
7743
7744 if (*curr).state == 1 {
7745 current_process = curr;
7746 if (*curr).cr3_phys != 0 {
7747 asm { "mov cr3, %0" in "r"((*curr).cr3_phys); }
7748 }
7749 }
7750 }
7751
7752 struct AegisCap {
7753 uid: u32,
7754 net_access: bool,
7755 fs_access: bool,
7756 hw_access: bool,
7757 }
7758
7759 fn aegis_verify(proc: ptr<ProcessControlBlock>, req_cap: u8) -> bool {
7760 if proc == (0 as ptr<ProcessControlBlock>) { return false; }
7761 if (*proc).privilege_level == 0 { return true; }
7762 return false;
7763 }
7764
7765 fn syscall_handler() {
7766 let mut eax: u32 = 0;
7767 let mut ebx: u32 = 0;
7768 let mut ecx: u32 = 0;
7769 let mut edx: u32 = 0;
7770
7771 asm {
7772 "mov %0, eax\n"
7773 "mov %1, ebx\n"
7774 "mov %2, ecx\n"
7775 "mov %3, edx\n"
7776 inout "=r"(eax), "=r"(ebx), "=r"(ecx), "=r"(edx);
7777 }
7778
7779 let mut ret_val: u32 = 0xFFFFFFFF;
7780 if eax == 1 {
7781 ret_val = kmalloc(ebx as u64) as u32;
7782 } else if eax == 2 {
7783 kfree(ebx as ptr<u8>);
7784 ret_val = 0;
7785 } else if eax == 3 {
7786 wm_crt(ebx, ecx);
7787 ret_val = 0;
7788 } else if eax == 4 {
7789 tcp_syn(0, ebx as u16, ecx as u16);
7790 ret_val = 0;
7791 } else if eax == 5 {
7792 crypto_init();
7793 ret_val = 0;
7794 }
7795
7796 asm {
7797 "mov eax, %0\n"
7798 in "r"(ret_val);
7799 }
7800 }
7801
7802 fn idle_t() { loop { cpu_hlt(); sched(); } }
7803 fn gui_t() { loop { wm_cmp(); sched(); } }
7804 fn net_t() { loop { arp_req(0); sched(); } }
7805
7806 #[no_mangle]
7807 pub fn _start() -> ! {
7808 cpu_cli();
7809 init_gdt_smp();
7810 init_idt_smp();
7811 pmm_init(256 * 1024 * 1024);
7812 vmm_init();
7813 init_apic_smp();
7814
7815 crypto_init();
7816 vfs_init();
7817
7818 create_process(idle_t as u64, true);
7819 create_process(gui_t as u64, true);
7820 create_process(net_t as u64, true);
7821
7822 cpu_sti();
7823 loop {
7824 sched();
7825 cpu_pause();
7826 }
7827 }
7828
7829 const DRIVER_TYPE_NETWORK: u8 = 1;
7830 const DRIVER_TYPE_STORAGE: u8 = 2;
7831 const DRIVER_TYPE_DISPLAY: u8 = 3;
7832 const DRIVER_TYPE_AUDIO: u8 = 4;
7833 const DRIVER_TYPE_INPUT: u8 = 5;
7834 const DRIVER_TYPE_USB_HC: u8 = 6;
7835
7836 struct DeviceDriver {
7837 name: [u8; 32],
7838 drv_type: u8,
7839 init_func: u64,
7840 read_func: u64,
7841 write_func: u64,
7842 irq_handler: u64,
7843 is_loaded: bool,
7844 }
7845
7846 let mut global_driver_registry: [DeviceDriver; 1024];
7847 let mut registered_driver_count: u32 = 0;
7848
7849 fn register_driver(name: ptr<u8>, d_type: u8, init: u64, read: u64, write: u64, irq: u64) {
7850 if registered_driver_count >= 1024 || name == (0 as ptr<u8>) { return; }
7851 let drv = &mut global_driver_registry[registered_driver_count as usize];
7852 let len = strlen(name);
7853 let copy_len = if len >= 31 { 31 } else { len };
7854 memcpy(&mut drv.name[0] as ptr<u8>, name, copy_len);
7855 drv.name[copy_len as usize] = 0;
7856 drv.drv_type = d_type;
7857 drv.init_func = init;
7858 drv.read_func = read;
7859 drv.write_func = write;
7860 drv.irq_handler = irq;
7861 drv.is_loaded = false;
7862 registered_driver_count = registered_driver_count + 1;
7863 }
7864
7865 fn drv_e1000_init() -> bool { shell_print_string("Loading Intel PRO/1000...\n" as ptr<u8>); return true; }
7866 fn drv_e1000e_init() -> bool { shell_print_string("Loading Intel PCIe Gigabit...\n" as ptr<u8>); return true; }
7867 fn drv_ixgbe_init() -> bool { shell_print_string("Loading Intel 10GbE...\n" as ptr<u8>); return true; }
7868 fn drv_rtl8139_init() -> bool { shell_print_string("Loading Realtek 8139...\n" as ptr<u8>); return true; }
7869 fn drv_rtl8168_init() -> bool { shell_print_string("Loading Realtek 8168/8111...\n" as ptr<u8>); return true; }
7870 fn drv_virtio_net_init() -> bool { shell_print_string("Loading VirtIO Network...\n" as ptr<u8>); return true; }
7871 fn drv_broadcom_net_init() -> bool { shell_print_string("Loading Broadcom NetXtreme...\n" as ptr<u8>); return true; }
7872 fn drv_atheros_wifi_init() -> bool { shell_print_string("Loading Atheros 802.11...\n" as ptr<u8>); return true; }
7873 fn drv_intel_wifi_init() -> bool { shell_print_string("Loading Intel Wireless WiFi...\n" as ptr<u8>); return true; }
7874 fn drv_ahci_init() -> bool { shell_print_string("Loading AHCI SATA Controller...\n" as ptr<u8>); return true; }
7875 fn drv_nvme_init() -> bool { shell_print_string("Loading NVMe Controller...\n" as ptr<u8>); return true; }
7876 fn drv_ide_init() -> bool { shell_print_string("Loading Legacy IDE Controller...\n" as ptr<u8>); return true; }
7877 fn drv_virtio_blk_init() -> bool { shell_print_string("Loading VirtIO Block...\n" as ptr<u8>); return true; }
7878 fn drv_sdhci_init() -> bool { shell_print_string("Loading SD Host Controller...\n" as ptr<u8>); return true; }
7879 fn drv_lsi_sas_init() -> bool { shell_print_string("Loading LSI SAS Controller...\n" as ptr<u8>); return true; }
7880 fn drv_xhci_init() -> bool { shell_print_string("Loading USB 3.0 xHCI...\n" as ptr<u8>); return true; }
7881 fn drv_ehci_init() -> bool { shell_print_string("Loading USB 2.0 EHCI...\n" as ptr<u8>); return true; }
7882 fn drv_uhci_init() -> bool { shell_print_string("Loading USB 1.1 UHCI...\n" as ptr<u8>); return true; }
7883 fn drv_ohci_init() -> bool { shell_print_string("Loading USB 1.0 OHCI...\n" as ptr<u8>); return true; }
7884 fn drv_intel_gma_init() -> bool { shell_print_string("Loading Intel GMA/HD Graphics...\n" as ptr<u8>); return true; }
7885 fn drv_amd_radeon_init() -> bool { shell_print_string("Loading AMD Radeon Graphics...\n" as ptr<u8>); return true; }
7886 fn drv_nvidia_nouveau_init() -> bool { shell_print_string("Loading Nvidia (Nouveau) Graphics...\n" as ptr<u8>); return true; }
7887 fn drv_virtio_gpu_init() -> bool { shell_print_string("Loading VirtIO GPU...\n" as ptr<u8>); return true; }
7888 fn drv_vbox_video_init() -> bool { shell_print_string("Loading VirtualBox Video...\n" as ptr<u8>); return true; }
7889 fn drv_vmware_svga_init() -> bool { shell_print_string("Loading VMware SVGA II...\n" as ptr<u8>); return true; }
7890 fn drv_bochs_vbe_init() -> bool { shell_print_string("Loading Bochs VBE Display...\n" as ptr<u8>); return true; }
7891 fn drv_intel_hda_init() -> bool { shell_print_string("Loading Intel High Definition Audio...\n" as ptr<u8>); return true; }
7892 fn drv_ac97_init() -> bool { shell_print_string("Loading AC97 Audio...\n" as ptr<u8>); return true; }
7893 fn drv_sb16_init() -> bool { shell_print_string("Loading Sound Blaster 16...\n" as ptr<u8>); return true; }
7894 fn drv_ps2_kbd_init() -> bool { shell_print_string("Loading PS/2 Keyboard...\n" as ptr<u8>); return true; }
7895 fn drv_ps2_mouse_init() -> bool { shell_print_string("Loading PS/2 Mouse...\n" as ptr<u8>); return true; }
7896 fn drv_usb_hid_init() -> bool { shell_print_string("Loading USB HID (Kbd/Mouse)...\n" as ptr<u8>); return true; }
7897 fn drv_i2c_hid_init() -> bool { shell_print_string("Loading I2C HID Touchpad...\n" as ptr<u8>); return true; }
7898
7899 fn uda_register_all_drivers() {
7900 register_driver("e1000" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_e1000_init as u64, 0, 0, 0);
7901 register_driver("e1000e" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_e1000e_init as u64, 0, 0, 0);
7902 register_driver("ixgbe" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_ixgbe_init as u64, 0, 0, 0);
7903 register_driver("rtl8139" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_rtl8139_init as u64, 0, 0, 0);
7904 register_driver("rtl8168" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_rtl8168_init as u64, 0, 0, 0);
7905 register_driver("virtio-net" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_virtio_net_init as u64, 0, 0, 0);
7906 register_driver("bcm-net" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_broadcom_net_init as u64, 0, 0, 0);
7907 register_driver("ath-wifi" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_atheros_wifi_init as u64, 0, 0, 0);
7908 register_driver("iwlwifi" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_intel_wifi_init as u64, 0, 0, 0);
7909
7910 register_driver("ahci" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_ahci_init as u64, 0, 0, 0);
7911 register_driver("nvme" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_nvme_init as u64, 0, 0, 0);
7912 register_driver("ide" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_ide_init as u64, 0, 0, 0);
7913 register_driver("virtio-blk" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_virtio_blk_init as u64, 0, 0, 0);
7914 register_driver("sdhci" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_sdhci_init as u64, 0, 0, 0);
7915 register_driver("lsi-sas" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_lsi_sas_init as u64, 0, 0, 0);
7916
7917 register_driver("xhci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_xhci_init as u64, 0, 0, 0);
7918 register_driver("ehci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_ehci_init as u64, 0, 0, 0);
7919 register_driver("uhci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_uhci_init as u64, 0, 0, 0);
7920 register_driver("ohci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_ohci_init as u64, 0, 0, 0);
7921
7922 register_driver("intel-gma" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_intel_gma_init as u64, 0, 0, 0);
7923 register_driver("amd-radeon" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_amd_radeon_init as u64, 0, 0, 0);
7924 register_driver("nvidia" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_nvidia_nouveau_init as u64, 0, 0, 0);
7925 register_driver("virtio-gpu" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_virtio_gpu_init as u64, 0, 0, 0);
7926 register_driver("vbox-video" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_vbox_video_init as u64, 0, 0, 0);
7927 register_driver("vmware-svga" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_vmware_svga_init as u64, 0, 0, 0);
7928 register_driver("bochs-vbe" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_bochs_vbe_init as u64, 0, 0, 0);
7929
7930 register_driver("intel-hda" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_intel_hda_init as u64, 0, 0, 0);
7931 register_driver("ac97" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_ac97_init as u64, 0, 0, 0);
7932 register_driver("sb16" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_sb16_init as u64, 0, 0, 0);
7933
7934 register_driver("ps2-kbd" as ptr<u8>, DRIVER_TYPE_INPUT, drv_ps2_kbd_init as u64, 0, 0, 0);
7935 register_driver("ps2-mouse" as ptr<u8>, DRIVER_TYPE_INPUT, drv_ps2_mouse_init as u64, 0, 0, 0);
7936 register_driver("usb-hid" as ptr<u8>, DRIVER_TYPE_INPUT, drv_usb_hid_init as u64, 0, 0, 0);
7937 register_driver("i2c-hid" as ptr<u8>, DRIVER_TYPE_INPUT, drv_i2c_hid_init as u64, 0, 0, 0);
7938 }
7939
7940 fn get_pci_vendor_name(vendor_id: u16) -> ptr<u8> {
7941 if vendor_id == 0x8086 { return "Intel Corporation" as ptr<u8>; }
7942 if vendor_id == 0x1002 { return "Advanced Micro Devices (AMD)" as ptr<u8>; }
7943 if vendor_id == 0x10DE { return "NVIDIA Corporation" as ptr<u8>; }
7944 if vendor_id == 0x10EC { return "Realtek Semiconductor Co., Ltd." as ptr<u8>; }
7945 if vendor_id == 0x14E4 { return "Broadcom Inc. and subsidiaries" as ptr<u8>; }
7946 if vendor_id == 0x1AF4 { return "Red Hat, Inc. (Virtio)" as ptr<u8>; }
7947 if vendor_id == 0x15AD { return "VMware" as ptr<u8>; }
7948 if vendor_id == 0x80EE { return "InnoTek Systemberatung GmbH (VirtualBox)" as ptr<u8>; }
7949 if vendor_id == 0x1022 { return "AMD (Legacy)" as ptr<u8>; }
7950 if vendor_id == 0x104C { return "Texas Instruments" as ptr<u8>; }
7951 if vendor_id == 0x11AB { return "Marvell Technology Group Ltd." as ptr<u8>; }
7952 if vendor_id == 0x197B { return "JMicron Technology Corp." as ptr<u8>; }
7953 if vendor_id == 0x1014 { return "IBM" as ptr<u8>; }
7954 if vendor_id == 0x0E11 { return "Compaq Computer Corporation" as ptr<u8>; }
7955 if vendor_id == 0x103C { return "Hewlett-Packard Company" as ptr<u8>; }
7956 if vendor_id == 0x1028 { return "Dell" as ptr<u8>; }
7957 if vendor_id == 0x1043 { return "ASUSTeK Computer Inc." as ptr<u8>; }
7958 if vendor_id == 0x1458 { return "Gigabyte Technology Co., Ltd" as ptr<u8>; }
7959 if vendor_id == 0x1462 { return "Micro-Star International Co., Ltd. [MSI]" as ptr<u8>; }
7960 if vendor_id == 0x15B3 { return "Mellanox Technologies" as ptr<u8>; }
7961 if vendor_id == 0x1B36 { return "Red Hat, Inc. (QEMU)" as ptr<u8>; }
7962 if vendor_id == 0x1C58 { return "HGST, Inc." as ptr<u8>; }
7963 if vendor_id == 0x144D { return "Samsung Electronics Co Ltd" as ptr<u8>; }
7964 if vendor_id == 0x152D { return "JMicron Technology Corp. (NVMe)" as ptr<u8>; }
7965 if vendor_id == 0x1D0F { return "Amazon.com, Inc." as ptr<u8>; }
7966 if vendor_id == 0x1AE0 { return "Google, Inc." as ptr<u8>; }
7967 if vendor_id == 0x106B { return "Apple Inc." as ptr<u8>; }
7968 if vendor_id == 0x105A { return "Promise Technology, Inc." as ptr<u8>; }
7969 if vendor_id == 0x10B5 { return "PLX Technology, Inc." as ptr<u8>; }
7970 if vendor_id == 0x10DF { return "Emulex Corporation" as ptr<u8>; }
7971 if vendor_id == 0x1106 { return "VIA Technologies, Inc." as ptr<u8>; }
7972 if vendor_id == 0x1179 { return "Toshiba Corporation" as ptr<u8>; }
7973 if vendor_id == 0x1186 { return "D-Link System Inc" as ptr<u8>; }
7974 if vendor_id == 0x13F0 { return "Sundance Technology Inc / IC Plus Corp" as ptr<u8>; }
7975 if vendor_id == 0x168C { return "Qualcomm Atheros" as ptr<u8>; }
7976 if vendor_id == 0x1814 { return "Ralink corp." as ptr<u8>; }
7977 if vendor_id == 0x1B21 { return "ASMedia Technology Inc." as ptr<u8>; }
7978 if vendor_id == 0x8087 { return "Intel Corporation (Wireless)" as ptr<u8>; }
7979 return "Unknown Vendor" as ptr<u8>;
7980 }
7981
7982 fn get_pci_device_name(vendor_id: u16, device_id: u16) -> ptr<u8> {
7983 if vendor_id == 0x8086 {
7984 if device_id == 0x100E { return "Gigabit Ethernet Controller (e1000)" as ptr<u8>; }
7985 if device_id == 0x100F { return "Gigabit Ethernet Controller (e1000)" as ptr<u8>; }
7986 if device_id == 0x10D3 { return "82574L Gigabit Network Connection" as ptr<u8>; }
7987 if device_id == 0x10EA { return "82577LM Gigabit Network Connection" as ptr<u8>; }
7988 if device_id == 0x1502 { return "82579LM Gigabit Network Connection" as ptr<u8>; }
7989 if device_id == 0x1503 { return "82579V Gigabit Network Connection" as ptr<u8>; }
7990 if device_id == 0x153A { return "I217-LM Gigabit Network Connection" as ptr<u8>; }
7991 if device_id == 0x153B { return "I217-V Gigabit Network Connection" as ptr<u8>; }
7992 if device_id == 0x15B7 { return "I219-LM Gigabit Network Connection" as ptr<u8>; }
7993 if device_id == 0x15B8 { return "I219-V Gigabit Network Connection" as ptr<u8>; }
7994 if device_id == 0x10FB { return "82599ES 10-Gigabit SFI/SFP+ Network Connection" as ptr<u8>; }
7995 if device_id == 0x1528 { return "Ethernet Controller 10-Gigabit X540-AT2" as ptr<u8>; }
7996 if device_id == 0x2922 { return "82801IR/IO/P (ICH9) 6 port SATA Controller [AHCI mode]" as ptr<u8>; }
7997 if device_id == 0x1C02 { return "6 Series/C200 Series Chipset Family 6 port SATA AHCI" as ptr<u8>; }
7998 if device_id == 0x1E02 { return "7 Series/C210 Series Chipset Family 6-port SATA Controller" as ptr<u8>; }
7999 if device_id == 0x8C02 { return "8 Series/C220 Series Chipset Family 6-port SATA Controller" as ptr<u8>; }
8000 if device_id == 0xA102 { return "100 Series/C230 Series Chipset Family SATA AHCI" as ptr<u8>; }
8001 if device_id == 0xA282 { return "200 Series/Z370 Chipset Family SATA AHCI Controller" as ptr<u8>; }
8002 if device_id == 0x0116 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
8003 if device_id == 0x0166 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
8004 if device_id == 0x0412 { return "4th Gen Core Processor Integrated Graphics Controller" as ptr<u8>; }
8005 if device_id == 0x1912 { return "HD Graphics 530" as ptr<u8>; }
8006 if device_id == 0x3E92 { return "UHD Graphics 630 (Desktop)" as ptr<u8>; }
8007 if device_id == 0x9BC5 { return "CometLake-S GT2 [UHD Graphics 630]" as ptr<u8>; }
8008 if device_id == 0x2668 { return "82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio" as ptr<u8>; }
8009 if device_id == 0x284B { return "82801H (ICH8 Family) High Definition Audio Controller" as ptr<u8>; }
8010 if device_id == 0x293E { return "82801I (ICH9 Family) High Definition Audio Controller" as ptr<u8>; }
8011 if device_id == 0x1E20 { return "7 Series/C210 Series Chipset Family High Definition Audio" as ptr<u8>; }
8012 if device_id == 0xA170 { return "100 Series/C230 Series Chipset Family HD Audio Controller" as ptr<u8>; }
8013 if device_id == 0x8C31 { return "8 Series/C220 Series Chipset Family USB xHCI" as ptr<u8>; }
8014 if device_id == 0xA12F { return "100 Series/C230 Series Chipset Family USB 3.0 xHCI" as ptr<u8>; }
8015 if device_id == 0x1E2D { return "7 Series/C210 Series Chipset Family USB Enhanced Host Controller" as ptr<u8>; }
8016 if device_id == 0x24C2 { return "82801DB/DBM (ICH4/ICH4-M) USB UHCI Controller" as ptr<u8>; }
8017 if device_id == 0xF1A5 { return "NVMe SSD Controller (Optane/760p)" as ptr<u8>; }
8018 if device_id == 0x4220 { return "PRO/Wireless 2200BG [Calexico2] Network Connection" as ptr<u8>; }
8019 if device_id == 0x4229 { return "PRO/Wireless 4965 AG or AGN [Kedron] Network Connection" as ptr<u8>; }
8020 if device_id == 0x0085 { return "Centrino Advanced-N 6205 [Taylor Peak]" as ptr<u8>; }
8021 if device_id == 0x08B1 { return "Wireless 7260" as ptr<u8>; }
8022 if device_id == 0x24FB { return "Dual Band Wireless-AC 3160" as ptr<u8>; }
8023 if device_id == 0x24FD { return "Dual Band Wireless-AC 8265" as ptr<u8>; }
8024 if device_id == 0x2723 { return "Wi-Fi 6 AX200" as ptr<u8>; }
8025 return "Intel Unknown Device" as ptr<u8>;
8026 }
8027 if vendor_id == 0x10EC {
8028 if device_id == 0x8139 { return "RTL-8100/8101L/8139 PCI Fast Ethernet Adapter" as ptr<u8>; }
8029 if device_id == 0x8168 { return "RTL8111/8168/8411 PCI Express Gigabit Ethernet" as ptr<u8>; }
8030 if device_id == 0x8125 { return "RTL8125 2.5GbE Controller" as ptr<u8>; }
8031 return "Realtek Unknown Device" as ptr<u8>;
8032 }
8033 if vendor_id == 0x1AF4 {
8034 if device_id == 0x1000 { return "Virtio Network Device" as ptr<u8>; }
8035 if device_id == 0x1001 { return "Virtio Block Device" as ptr<u8>; }
8036 if device_id == 0x1002 { return "Virtio Memory Balloon" as ptr<u8>; }
8037 if device_id == 0x1003 { return "Virtio Console" as ptr<u8>; }
8038 if device_id == 0x1050 { return "Virtio GPU Device" as ptr<u8>; }
8039 return "Virtio Unknown Device" as ptr<u8>;
8040 }
8041 return "Unknown PCI Device" as ptr<u8>;
8042 }
8043
8044 // --- REALTEK DEVICES ---
8045 if vendor_id == 0x10EC {
8046 if device_id == 0x8139 { return "RTL-8100/8101L/8139 PCI Fast Ethernet Adapter" as ptr<u8>; }
8047 if device_id == 0x8168 { return "RTL8111/8168/8411 PCI Express Gigabit Ethernet" as ptr<u8>; }
8048 if device_id == 0x8169 { return "RTL8169 PCI Gigabit Ethernet Controller" as ptr<u8>; }
8049 if device_id == 0x8125 { return "RTL8125 2.5GbE Controller" as ptr<u8>; }
8050 if device_id == 0x818B { return "RTL8192EE PCIe Wireless Network Adapter" as ptr<u8>; }
8051 if device_id == 0x8821 { return "RTL8821AE 802.11ac PCIe Wireless Network Adapter" as ptr<u8>; }
8052 if device_id == 0x8822 { return "RTL8822BE 802.11a/b/g/n/ac WiFi adapter" as ptr<u8>; }
8053 if device_id == 0x522A { return "RTS522A PCI Express Card Reader" as ptr<u8>; }
8054 if device_id == 0x0282 { return "RTL8188EE Wireless Network Adapter" as ptr<u8>; }
8055 return "Realtek Unknown Device" as ptr<u8>;
8056 }
8057
8058 // --- NVIDIA DEVICES ---
8059 if vendor_id == 0x10DE {
8060 if device_id == 0x0402 { return "GeForce 8600 GT" as ptr<u8>; }
8061 if device_id == 0x0611 { return "GeForce 8800 GT" as ptr<u8>; }
8062 if device_id == 0x0A20 { return "GeForce GT 220" as ptr<u8>; }
8063 if device_id == 0x06C0 { return "GeForce GTX 480" as ptr<u8>; }
8064 if device_id == 0x1080 { return "GeForce GTX 580" as ptr<u8>; }
8065 if device_id == 0x1180 { return "GeForce GTX 680" as ptr<u8>; }
8066 if device_id == 0x13C2 { return "GeForce GTX 970" as ptr<u8>; }
8067 if device_id == 0x13C0 { return "GeForce GTX 980" as ptr<u8>; }
8068 if device_id == 0x1C03 { return "GeForce GTX 1060 6GB" as ptr<u8>; }
8069 if device_id == 0x1B81 { return "GeForce GTX 1070" as ptr<u8>; }
8070 if device_id == 0x1B06 { return "GeForce GTX 1080 Ti" as ptr<u8>; }
8071 if device_id == 0x1E84 { return "GeForce RTX 2070" as ptr<u8>; }
8072 if device_id == 0x1E07 { return "GeForce RTX 2080 Ti" as ptr<u8>; }
8073 if device_id == 0x2204 { return "GeForce RTX 3090" as ptr<u8>; }
8074 if device_id == 0x2484 { return "GeForce RTX 3070" as ptr<u8>; }
8075 if device_id == 0x2684 { return "GeForce RTX 4090" as ptr<u8>; }
8076 if device_id == 0x28E0 { return "GeForce RTX 4050 Laptop GPU" as ptr<u8>; } // YBG13's PC!
8077 if device_id == 0x0E0A { return "GF119 HDMI Audio Controller" as ptr<u8>; }
8078 if device_id == 0x0FB0 { return "GM200 High Definition Audio" as ptr<u8>; }
8079 if device_id == 0x10F0 { return "GP104 High Definition Audio Controller" as ptr<u8>; }
8080 if device_id == 0x10FA { return "TU104 HD Audio Controller" as ptr<u8>; }
8081 return "NVIDIA Unknown Device" as ptr<u8>;
8082 }
8083
8084 // --- AMD/ATI DEVICES ---
8085 if vendor_id == 0x1002 {
8086 if device_id == 0x6738 { return "Radeon HD 6870" as ptr<u8>; }
8087 if device_id == 0x6798 { return "Radeon HD 7970 / R9 280X" as ptr<u8>; }
8088 if device_id == 0x67B1 { return "Radeon R9 290 / 390" as ptr<u8>; }
8089 if device_id == 0x67DF { return "Radeon RX 470/480/570/580/590" as ptr<u8>; }
8090 if device_id == 0x687F { return "Radeon RX Vega 56/64" as ptr<u8>; }
8091 if device_id == 0x731F { return "Radeon RX 5700 XT" as ptr<u8>; }
8092 if device_id == 0x73BF { return "Radeon RX 6800 XT / 6900 XT" as ptr<u8>; }
8093 if device_id == 0x744C { return "Radeon RX 7900 XTX" as ptr<u8>; }
8094 if device_id == 0x4383 { return "SB7x0/SB8x0/SB9x0 High Definition Audio Controller" as ptr<u8>; }
8095 if device_id == 0x1457 { return "Family 17h (Models 00h-0fh) HD Audio Controller" as ptr<u8>; }
8096 if device_id == 0x4391 { return "SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode]" as ptr<u8>; }
8097 if device_id == 0x7901 { return "FCH SATA Controller [AHCI mode]" as ptr<u8>; }
8098 return "AMD/ATI Unknown Device" as ptr<u8>;
8099 }
8100
8101 // --- VIRTUALIZATION DEVICES (VIRTIO, VMWARE, VBOX) ---
8102 if vendor_id == 0x1AF4 {
8103 if device_id == 0x1000 { return "VirtIO Network Device" as ptr<u8>; }
8104 if device_id == 0x1001 { return "VirtIO Block Device" as ptr<u8>; }
8105 if device_id == 0x1002 { return "VirtIO Memory Balloon" as ptr<u8>; }
8106 if device_id == 0x1003 { return "VirtIO Console" as ptr<u8>; }
8107 if device_id == 0x1004 { return "VirtIO SCSI" as ptr<u8>; }
8108 if device_id == 0x1005 { return "VirtIO RNG" as ptr<u8>; }
8109 if device_id == 0x1041 { return "VirtIO Network Device (Modern)" as ptr<u8>; }
8110 if device_id == 0x1042 { return "VirtIO Block Device (Modern)" as ptr<u8>; }
8111 if device_id == 0x1050 { return "VirtIO GPU" as ptr<u8>; }
8112 return "VirtIO Unknown Device" as ptr<u8>;
8113 }
8114 if vendor_id == 0x15AD {
8115 if device_id == 0x0405 { return "VMware SVGA II Adapter" as ptr<u8>; }
8116 if device_id == 0x07B0 { return "VMware VMXNET3 Ethernet Controller" as ptr<u8>; }
8117 if device_id == 0x07A0 { return "VMware PVSCSI SCSI Controller" as ptr<u8>; }
8118 return "VMware Unknown Device" as ptr<u8>;
8119 }
8120 if vendor_id == 0x80EE {
8121 if device_id == 0xBEEF { return "VirtualBox Graphics Adapter" as ptr<u8>; }
8122 if device_id == 0xCAFE { return "VirtualBox Guest Service" as ptr<u8>; }
8123 return "VirtualBox Unknown Device" as ptr<u8>;
8124 }
8125
8126 // --- STORAGE/SAMSUNG/BROADCOM AND OTHERS ---
8127 if vendor_id == 0x144D {
8128 if device_id == 0xA802 { return "Samsung SM951 NVMe" as ptr<u8>; }
8129 if device_id == 0xA804 { return "Samsung 960 EVO/PRO NVMe" as ptr<u8>; }
8130 if device_id == 0xA808 { return "Samsung 970 EVO/PRO NVMe" as ptr<u8>; }
8131 if device_id == 0xA80A { return "Samsung 980 PRO NVMe" as ptr<u8>; }
8132 if device_id == 0xA80C { return "Samsung 990 PRO NVMe" as ptr<u8>; }
8133 return "Samsung NVMe Unknown" as ptr<u8>;
8134 }
8135 if vendor_id == 0x14E4 {
8136 if device_id == 0x1659 { return "NetXtreme BCM5721 Gigabit Ethernet" as ptr<u8>; }
8137 if device_id == 0x1677 { return "NetXtreme BCM5751 Gigabit Ethernet" as ptr<u8>; }
8138 if device_id == 0x4311 { return "BCM4311 802.11b/g WLAN" as ptr<u8>; }
8139 if device_id == 0x4322 { return "BCM4322 802.11a/b/g/n Wireless LAN" as ptr<u8>; }
8140 if device_id == 0x4360 { return "BCM4360 802.11ac Wireless Network Adapter" as ptr<u8>; }
8141 return "Broadcom Unknown Device" as ptr<u8>;
8142 }
8143 if vendor_id == 0x168C {
8144 if device_id == 0x002B { return "AR9285 Wireless Network Adapter" as ptr<u8>; }
8145 if device_id == 0x002E { return "AR9287 Wireless Network Adapter" as ptr<u8>; }
8146 if device_id == 0x0032 { return "AR9485 Wireless Network Adapter" as ptr<u8>; }
8147 if device_id == 0x003C { return "QCA986x/988x 802.11ac Wireless Network Adapter" as ptr<u8>; }
8148 return "Atheros Unknown Device" as ptr<u8>;
8149 }
8150 return "Generic Unknown PCI Device" as ptr<u8>;
8151 }
8152 struct PciDeviceInfo {
8153 bus: u8,
8154 slot: u8,
8155 func: u8,
8156 vendor_id: u16,
8157 device_id: u16,
8158 class_code: u8,
8159 subclass: u8,
8160 prog_if: u8,
8161 irq: u8,
8162 bar0: u32,
8163 bar1: u32,
8164 bar2: u32,
8165 bar3: u32,
8166 bar4: u32,
8167 bar5: u32,
8168 is_active: bool,
8169 }
8170 let mut pci_device_tree: [PciDeviceInfo; 256];
8171 let mut pci_device_count: u32 = 0;
8172 fn pci_config_read_word(bus: u8, slot: u8, func: u8, offset: u8) -> u16 {
8173 let address: u32 = ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32 & 0xFC) | 0x80000000;
8174 outl(0xCF8, address);
8175 let tmp = inl(0xCFC);
8176 return ((tmp >> ((offset & 2) * 8)) & 0xFFFF) as u16;
8177 }
8178 fn pci_config_read_dword(bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
8179 let address: u32 = ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32 & 0xFC) | 0x80000000;
8180 outl(0xCF8, address);
8181 return inl(0xCFC);
8182 }
8183 fn uda_probe_pci_bus() {
8184 shell_print_string("UDA: Probing PCI/PCIe Busses...\n" as ptr<u8>);
8185 for bus in 0..=255 {
8186 for slot in 0..32 {
8187 let vendor_id = pci_config_read_word(bus as u8, slot as u8, 0, 0);
8188 if vendor_id != 0xFFFF {
8189 let device_id = pci_config_read_word(bus as u8, slot as u8, 0, 2);
8190 let class_subclass = pci_config_read_word(bus as u8, slot as u8, 0, 0x0A);
8191 let class_code = (class_subclass >> 8) as u8;
8192 let subclass = (class_subclass & 0xFF) as u8;
8193 let prog_if = (pci_config_read_word(bus as u8, slot as u8, 0, 0x08) >> 8) as u8;
8194
8195 if pci_device_count < 256 {
8196 let dev = &pci_device_tree[pci_device_count as usize];
8197 dev.bus = bus as u8;
8198 dev.slot = slot as u8;
8199 dev.func = 0;
8200 dev.vendor_id = vendor_id;
8201 dev.device_id = device_id;
8202 dev.class_code = class_code;
8203 dev.subclass = subclass;
8204 dev.prog_if = prog_if;
8205 dev.is_active = true;
8206
8207 dev.bar0 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x10);
8208 dev.bar1 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x14);
8209 dev.bar2 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x18);
8210 dev.bar3 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x1C);
8211 dev.bar4 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x20);
8212 dev.bar5 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x24);
8213 dev.irq = (pci_config_read_word(bus as u8, slot as u8, 0, 0x3C) & 0xFF) as u8;
8214
8215 pci_device_count = pci_device_count + 1;
8216
8217 uda_match_and_load_driver(dev);
8218 }
8219 }
8220 }
8221 }
8222 shell_print_string("UDA: PCI Scan Complete. Found devices: " as ptr<u8>);
8223 let mut buf: [u8; 16];
8224 itoa(pci_device_count as i32, 10, &buf[0] as ptr<u8>);
8225 shell_print_string(&buf[0] as ptr<u8>);
8226 shell_print_string("\n" as ptr<u8>);
8227 }
8228 fn uda_match_and_load_driver(dev: ptr<PciDeviceInfo>) {
8229 let vid = (*dev).vendor_id;
8230 let did = (*dev).device_id;
8231 let cls = (*dev).class_code;
8232 let sub = (*dev).subclass;
8233 let p_if = (*dev).prog_if;
8234 // --- Mass Storage Controllers ---
8235 if cls == 0x01 {
8236 if sub == 0x01 {
8237 drv_ide_init();
8238 } else if sub == 0x06 && p_if == 0x01 {
8239 drv_ahci_init();
8240 } else if sub == 0x08 && p_if == 0x02 {
8241 drv_nvme_init();
8242 }
8243 }
8244 else if cls == 0x02 {
8245 if sub == 0x00 { // Ethernet
8246 if vid == 0x8086 {
8247 if did == 0x100E || did == 0x100F { drv_e1000_init(); }
8248 else if did == 0x153A || did == 0x153B { drv_e1000e_init(); }
8249 else { drv_e1000e_init(); } // Generic fallback for intel network
8250 } else if vid == 0x10EC {
8251 if did == 0x8139 { drv_rtl8139_init(); }
8252 else if did == 0x8168 { drv_rtl8168_init(); }
8253 } else if vid == 0x1AF4 && did == 0x1000 {
8254 drv_virtio_net_init();
8255 }
8256 } else if sub == 0x80 { // Network controller (often WiFi)
8257 if vid == 0x8086 || vid == 0x8087 { drv_intel_wifi_init(); }
8258 else if vid == 0x168C { drv_atheros_wifi_init(); }
8259 }
8260 }
8261 else if cls == 0x03 {
8262 if vid == 0x8086 { drv_intel_gma_init(); }
8263 else if vid == 0x1002 { drv_amd_radeon_init(); }
8264 else if vid == 0x10DE { drv_nvidia_nouveau_init(); }
8265 else if vid == 0x15AD { drv_vmware_svga_init(); }
8266 else if vid == 0x80EE { drv_vbox_video_init(); }
8267 else if vid == 0x1AF4 { drv_virtio_gpu_init(); }
8268 else { drv_bochs_vbe_init(); }
8269 }
8270 else if cls == 0x04 {
8271 if sub == 0x01 { drv_ac97_init(); }
8272 else if sub == 0x03 { drv_intel_hda_init(); }
8273 }
8274 else if cls == 0x0C && sub == 0x03 {
8275 if p_if == 0x00 { drv_uhci_init(); }
8276 else if p_if == 0x10 { drv_ohci_init(); }
8277 else if p_if == 0x20 { drv_ehci_init(); }
8278 else if p_if == 0x30 { drv_xhci_init(); }
8279 }
8280 }
8281 fn uda_dump_device_tree() {
8282 shell_print_string("\n--- UDA DEVICE TREE DUMP ---\n" as ptr<u8>);
8283 for i in 0..pci_device_count {
8284 let dev = &pci_device_tree[i as usize];
8285 let v_name = get_pci_vendor_name(dev.vendor_id);
8286 let d_name = get_pci_device_name(dev.vendor_id, dev.device_id);
8287
8288 shell_print_string("BUS: " as ptr<u8>);
8289 let mut bbuf: [u8; 8]; itoa(dev.bus as i32, 10, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
8290
8291 shell_print_string(" | VID: 0x" as ptr<u8>);
8292 itoa(dev.vendor_id as i32, 16, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
8293
8294 shell_print_string(" | DID: 0x" as ptr<u8>);
8295 itoa(dev.device_id as i32, 16, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
8296
8297 shell_print_string("\n -> " as ptr<u8>);
8298 shell_print_string(v_name); shell_print_string(" - " as ptr<u8>); shell_print_string(d_name);
8299 shell_print_string("\n" as ptr<u8>);
8300 }
8301 shell_print_string("----------------------------\n" as ptr<u8>);
8302 }
8303 fn uda_thread() {
8304 uda_register_all_drivers();
8305 uda_probe_pci_bus();
8306 uda_dump_device_tree();
8307
8308 // UDA Daemon loop
8309 loop {
8310 // Here we would handle Hot-Plug events (PCIe Hotplug, USB Hotplug)
8311 cpu_pause();
8312 sched();
8313 }
8314 }
8315 fn drv_lsi_megaraid_init() -> bool { shell_print_string("Loading LSI MegaRAID SAS...\n" as ptr<u8>); return true; }
8316 fn drv_adaptec_raid_init() -> bool { shell_print_string("Loading Adaptec AACRAID...\n" as ptr<u8>); return true; }
8317 fn drv_promise_fasttrak_init() -> bool { shell_print_string("Loading Promise FastTrak RAID...\n" as ptr<u8>); return true; }
8318 fn drv_highpoint_rocketraid_init() -> bool { shell_print_string("Loading HighPoint RocketRAID...\n" as ptr<u8>); return true; }
8319 fn drv_via_sata_init() -> bool { shell_print_string("Loading VIA SATA Controller...\n" as ptr<u8>); return true; }
8320 fn drv_sis_sata_init() -> bool { shell_print_string("Loading SiS SATA Controller...\n" as ptr<u8>); return true; }
8321 fn drv_uli_sata_init() -> bool { shell_print_string("Loading ULi SATA Controller...\n" as ptr<u8>); return true; }
8322 fn drv_marvell_sata_init() -> bool { shell_print_string("Loading Marvell 88SE SATA...\n" as ptr<u8>); return true; }
8323 fn drv_jmicron_sata_init() -> bool { shell_print_string("Loading JMicron JMB36x SATA...\n" as ptr<u8>); return true; }
8324 fn drv_asmedia_sata_init() -> bool { shell_print_string("Loading ASMedia ASM106x SATA...\n" as ptr<u8>); return true; }
8325 fn drv_mellanox_cx_init() -> bool { shell_print_string("Loading Mellanox ConnectX 10/40/100GbE...\n" as ptr<u8>); return true; }
8326 fn drv_3com_3c905_init() -> bool { shell_print_string("Loading 3Com 3c905B Fast EtherLink...\n" as ptr<u8>); return true; }
8327 fn drv_dec_tulip_init() -> bool { shell_print_string("Loading DEC Tulip Ethernet...\n" as ptr<u8>); return true; }
8328 fn drv_sis_900_init() -> bool { shell_print_string("Loading SiS 900 PCI Fast Ethernet...\n" as ptr<u8>); return true; }
8329 fn drv_via_rhine_init() -> bool { shell_print_string("Loading VIA Rhine II Fast Ethernet...\n" as ptr<u8>); return true; }
8330 fn drv_via_velocity_init() -> bool { shell_print_string("Loading VIA Velocity Gigabit...\n" as ptr<u8>); return true; }
8331 fn drv_marvell_yukon_init() -> bool { shell_print_string("Loading Marvell Yukon Gigabit...\n" as ptr<u8>); return true; }
8332 fn drv_broadcom_tg3_init() -> bool { shell_print_string("Loading Broadcom Tigon3 Gigabit...\n" as ptr<u8>); return true; }
8333 fn drv_intel_10gbe_vf_init() -> bool { shell_print_string("Loading Intel 10GbE Virtual Function...\n" as ptr<u8>); return true; }
8334 fn drv_solarflare_init() -> bool { shell_print_string("Loading Solarflare 10/40GbE...\n" as ptr<u8>); return true; }
8335 fn drv_qlogic_net_init() -> bool { shell_print_string("Loading QLogic 10/25GbE...\n" as ptr<u8>); return true; }
8336 fn drv_matrox_g400_init() -> bool { shell_print_string("Loading Matrox G400/G450/G550...\n" as ptr<u8>); return true; }
8337 fn drv_3dfx_voodoo_init() -> bool { shell_print_string("Loading 3dfx Voodoo Graphics...\n" as ptr<u8>); return true; }
8338 fn drv_cirrus_logic_init() -> bool { shell_print_string("Loading Cirrus Logic GD5446...\n" as ptr<u8>); return true; }
8339 fn drv_s3_trio_init() -> bool { shell_print_string("Loading S3 Trio32/64...\n" as ptr<u8>); return true; }
8340 fn drv_s3_savage_init() -> bool { shell_print_string("Loading S3 Savage 3D...\n" as ptr<u8>); return true; }
8341 fn drv_via_chrome_init() -> bool { shell_print_string("Loading VIA UniChrome Graphics...\n" as ptr<u8>); return true; }
8342 fn drv_creative_emu10k1_init() -> bool { shell_print_string("Loading Creative Sound Blaster Live!...\n" as ptr<u8>); return true; }
8343 fn drv_creative_xifi_init() -> bool { shell_print_string("Loading Creative X-Fi Audio...\n" as ptr<u8>); return true; }
8344 fn drv_via_envy24_init() -> bool { shell_print_string("Loading VIA Envy24 Audio...\n" as ptr<u8>); return true; }
8345 fn drv_cmedia_cmi8738_init() -> bool { shell_print_string("Loading C-Media CMI8738 Audio...\n" as ptr<u8>); return true; }
8346 fn drv_cmedia_oxygen_init() -> bool { shell_print_string("Loading C-Media Oxygen HD Audio...\n" as ptr<u8>); return true; }
8347 fn drv_ess_solo1_init() -> bool { shell_print_string("Loading ESS Solo-1 Audio...\n" as ptr<u8>); return true; }
8348 fn drv_yamaha_ymf724_init() -> bool { shell_print_string("Loading Yamaha YMF724 Audio...\n" as ptr<u8>); return true; }
8349 fn drv_fresco_logic_xhci_init() -> bool { shell_print_string("Loading Fresco Logic xHCI USB 3.0...\n" as ptr<u8>); return true; }
8350 fn drv_renesas_xhci_init() -> bool { shell_print_string("Loading Renesas xHCI USB 3.0...\n" as ptr<u8>); return true; }
8351 fn drv_asmedia_xhci_init() -> bool { shell_print_string("Loading ASMedia xHCI USB 3.0/3.1...\n" as ptr<u8>); return true; }
8352 fn drv_via_xhci_init() -> bool { shell_print_string("Loading VIA xHCI USB 3.0...\n" as ptr<u8>); return true; }
8353 fn drv_ti_xhci_init() -> bool { shell_print_string("Loading Texas Instruments xHCI USB 3.0...\n" as ptr<u8>); return true; }
8354 fn drv_ti_firewire_init() -> bool { shell_print_string("Loading Texas Instruments IEEE 1394...\n" as ptr<u8>); return true; }
8355 fn drv_via_firewire_init() -> bool { shell_print_string("Loading VIA IEEE 1394 Firewire...\n" as ptr<u8>); return true; }
8356 fn drv_ricoh_firewire_init() -> bool { shell_print_string("Loading Ricoh IEEE 1394 Firewire...\n" as ptr<u8>); return true; }
8357 fn drv_ricoh_sd_init() -> bool { shell_print_string("Loading Ricoh SD/MMC Host Controller...\n" as ptr<u8>); return true; }
8358 fn drv_o2micro_sd_init() -> bool { shell_print_string("Loading O2Micro SD/MMC Host Controller...\n" as ptr<u8>); return true; }
8359 fn drv_ene_sd_init() -> bool { shell_print_string("Loading ENE Technology SD Host Controller...\n" as ptr<u8>); return true; }
8360 fn uda_register_extended_drivers() {
8361 register_driver("lsi_megaraid" as ptr<u8>, 2, drv_lsi_megaraid_init as u64, 0, 0, 0);
8362 register_driver("adaptec_raid" as ptr<u8>, 2, drv_adaptec_raid_init as u64, 0, 0, 0);
8363 register_driver("promise_raid" as ptr<u8>, 2, drv_promise_fasttrak_init as u64, 0, 0, 0);
8364 register_driver("highpoint_raid" as ptr<u8>, 2, drv_highpoint_rocketraid_init as u64, 0, 0, 0);
8365 register_driver("via_sata" as ptr<u8>, 2, drv_via_sata_init as u64, 0, 0, 0);
8366 register_driver("sis_sata" as ptr<u8>, 2, drv_sis_sata_init as u64, 0, 0, 0);
8367 register_driver("uli_sata" as ptr<u8>, 2, drv_uli_sata_init as u64, 0, 0, 0);
8368 register_driver("marvell_sata" as ptr<u8>, 2, drv_marvell_sata_init as u64, 0, 0, 0);
8369 register_driver("jmicron_sata" as ptr<u8>, 2, drv_jmicron_sata_init as u64, 0, 0, 0);
8370 register_driver("asmedia_sata" as ptr<u8>, 2, drv_asmedia_sata_init as u64, 0, 0, 0);
8371 register_driver("mellanox_cx" as ptr<u8>, 1, drv_mellanox_cx_init as u64, 0, 0, 0);
8372 register_driver("3com_3c905" as ptr<u8>, 1, drv_3com_3c905_init as u64, 0, 0, 0);
8373 register_driver("dec_tulip" as ptr<u8>, 1, drv_dec_tulip_init as u64, 0, 0, 0);
8374 register_driver("sis_900" as ptr<u8>, 1, drv_sis_900_init as u64, 0, 0, 0);
8375 register_driver("via_rhine" as ptr<u8>, 1, drv_via_rhine_init as u64, 0, 0, 0);
8376 register_driver("via_velocity" as ptr<u8>, 1, drv_via_velocity_init as u64, 0, 0, 0);
8377 register_driver("marvell_yukon" as ptr<u8>, 1, drv_marvell_yukon_init as u64, 0, 0, 0);
8378 register_driver("bcm_tg3" as ptr<u8>, 1, drv_broadcom_tg3_init as u64, 0, 0, 0);
8379 register_driver("intel_10gbe_vf" as ptr<u8>, 1, drv_intel_10gbe_vf_init as u64, 0, 0, 0);
8380 register_driver("solarflare" as ptr<u8>, 1, drv_solarflare_init as u64, 0, 0, 0);
8381 register_driver("qlogic_net" as ptr<u8>, 1, drv_qlogic_net_init as u64, 0, 0, 0);
8382 register_driver("matrox_g400" as ptr<u8>, 3, drv_matrox_g400_init as u64, 0, 0, 0);
8383 register_driver("3dfx_voodoo" as ptr<u8>, 3, drv_3dfx_voodoo_init as u64, 0, 0, 0);
8384 register_driver("cirrus_logic" as ptr<u8>, 3, drv_cirrus_logic_init as u64, 0, 0, 0);
8385 register_driver("s3_trio" as ptr<u8>, 3, drv_s3_trio_init as u64, 0, 0, 0);
8386 register_driver("s3_savage" as ptr<u8>, 3, drv_s3_savage_init as u64, 0, 0, 0);
8387 register_driver("via_chrome" as ptr<u8>, 3, drv_via_chrome_init as u64, 0, 0, 0);
8388 register_driver("sb_live" as ptr<u8>, 4, drv_creative_emu10k1_init as u64, 0, 0, 0);
8389 register_driver("sb_xifi" as ptr<u8>, 4, drv_creative_xifi_init as u64, 0, 0, 0);
8390 register_driver("via_envy24" as ptr<u8>, 4, drv_via_envy24_init as u64, 0, 0, 0);
8391 register_driver("cmi8738" as ptr<u8>, 4, drv_cmedia_cmi8738_init as u64, 0, 0, 0);
8392 register_driver("cmedia_oxygen" as ptr<u8>, 4, drv_cmedia_oxygen_init as u64, 0, 0, 0);
8393 register_driver("ess_solo1" as ptr<u8>, 4, drv_ess_solo1_init as u64, 0, 0, 0);
8394 register_driver("ymf724" as ptr<u8>, 4, drv_yamaha_ymf724_init as u64, 0, 0, 0);
8395 register_driver("fresco_xhci" as ptr<u8>, 6, drv_fresco_logic_xhci_init as u64, 0, 0, 0);
8396 register_driver("renesas_xhci" as ptr<u8>, 6, drv_renesas_xhci_init as u64, 0, 0, 0);
8397 register_driver("asmedia_xhci" as ptr<u8>, 6, drv_asmedia_xhci_init as u64, 0, 0, 0);
8398 register_driver("via_xhci" as ptr<u8>, 6, drv_via_xhci_init as u64, 0, 0, 0);
8399 register_driver("ti_xhci" as ptr<u8>, 6, drv_ti_xhci_init as u64, 0, 0, 0);
8400 register_driver("ti_firewire" as ptr<u8>, 2, drv_ti_firewire_init as u64, 0, 0, 0);
8401 register_driver("via_firewire" as ptr<u8>, 2, drv_via_firewire_init as u64, 0, 0, 0);
8402 register_driver("ricoh_firewire" as ptr<u8>, 2, drv_ricoh_firewire_init as u64, 0, 0, 0);
8403 register_driver("ricoh_sd" as ptr<u8>, 2, drv_ricoh_sd_init as u64, 0, 0, 0);
8404 register_driver("o2micro_sd" as ptr<u8>, 2, drv_o2micro_sd_init as u64, 0, 0, 0);
8405 register_driver("ene_sd" as ptr<u8>, 2, drv_ene_sd_init as u64, 0, 0, 0);
8406 }
8407 fn get_pci_vendor_name_ext(vendor_id: u16) -> ptr<u8> {
8408 if vendor_id == 0x8086 { return "Intel Corporation" as ptr<u8>; }
8409 if vendor_id == 0x1002 { return "Advanced Micro Devices, Inc. [AMD/ATI]" as ptr<u8>; }
8410 if vendor_id == 0x10DE { return "NVIDIA Corporation" as ptr<u8>; }
8411 if vendor_id == 0x10EC { return "Realtek Semiconductor Co., Ltd." as ptr<u8>; }
8412 if vendor_id == 0x14E4 { return "Broadcom Inc. and subsidiaries" as ptr<u8>; }
8413 if vendor_id == 0x1AF4 { return "Red Hat, Inc. [Virtio]" as ptr<u8>; }
8414 if vendor_id == 0x15AD { return "VMware" as ptr<u8>; }
8415 if vendor_id == 0x80EE { return "InnoTek Systemberatung GmbH [VirtualBox]" as ptr<u8>; }
8416 if vendor_id == 0x1022 { return "Advanced Micro Devices, Inc. [AMD]" as ptr<u8>; }
8417 if vendor_id == 0x104C { return "Texas Instruments" as ptr<u8>; }
8418 if vendor_id == 0x11AB { return "Marvell Technology Group Ltd." as ptr<u8>; }
8419 if vendor_id == 0x197B { return "JMicron Technology Corp." as ptr<u8>; }
8420 if vendor_id == 0x1014 { return "IBM Corporation" as ptr<u8>; }
8421 if vendor_id == 0x103C { return "Hewlett-Packard Company" as ptr<u8>; }
8422 if vendor_id == 0x1028 { return "Dell" as ptr<u8>; }
8423 if vendor_id == 0x1043 { return "ASUSTeK Computer Inc." as ptr<u8>; }
8424 if vendor_id == 0x1458 { return "Gigabyte Technology Co., Ltd" as ptr<u8>; }
8425 if vendor_id == 0x1462 { return "Micro-Star International Co., Ltd. [MSI]" as ptr<u8>; }
8426 if vendor_id == 0x15B3 { return "Mellanox Technologies" as ptr<u8>; }
8427 if vendor_id == 0x1B36 { return "Red Hat, Inc. [QEMU]" as ptr<u8>; }
8428 if vendor_id == 0x144D { return "Samsung Electronics Co Ltd" as ptr<u8>; }
8429 if vendor_id == 0x152D { return "JMicron Technology Corp. [NVMe]" as ptr<u8>; }
8430 if vendor_id == 0x1D0F { return "Amazon.com, Inc." as ptr<u8>; }
8431 if vendor_id == 0x1AE0 { return "Google, Inc." as ptr<u8>; }
8432 if vendor_id == 0x106B { return "Apple Inc." as ptr<u8>; }
8433 if vendor_id == 0x105A { return "Promise Technology, Inc." as ptr<u8>; }
8434 if vendor_id == 0x10B5 { return "PLX Technology, Inc." as ptr<u8>; }
8435 if vendor_id == 0x10DF { return "Emulex Corporation" as ptr<u8>; }
8436 if vendor_id == 0x1106 { return "VIA Technologies, Inc." as ptr<u8>; }
8437 if vendor_id == 0x1179 { return "Toshiba Corporation" as ptr<u8>; }
8438 if vendor_id == 0x1186 { return "D-Link System Inc" as ptr<u8>; }
8439 if vendor_id == 0x13F0 { return "Sundance Technology Inc / IC Plus Corp" as ptr<u8>; }
8440 if vendor_id == 0x168C { return "Qualcomm Atheros" as ptr<u8>; }
8441 if vendor_id == 0x1814 { return "Ralink corp." as ptr<u8>; }
8442 if vendor_id == 0x1B21 { return "ASMedia Technology Inc." as ptr<u8>; }
8443 if vendor_id == 0x8087 { return "Intel Corporation [Wireless]" as ptr<u8>; }
8444 if vendor_id == 0x1000 { return "LSI Logic / Symbios Logic" as ptr<u8>; }
8445 if vendor_id == 0x9005 { return "Adaptec" as ptr<u8>; }
8446 if vendor_id == 0x102B { return "Matrox Electronics Systems Ltd." as ptr<u8>; }
8447 if vendor_id == 0x121A { return "3Dfx Interactive, Inc." as ptr<u8>; }
8448 if vendor_id == 0x1013 { return "Cirrus Logic" as ptr<u8>; }
8449 if vendor_id == 0x104B { return "BusLogic" as ptr<u8>; }
8450 if vendor_id == 0x10EA { return "Intergraphics" as ptr<u8>; }
8451 if vendor_id == 0x108E { return "Sun Microsystems Computer Corp." as ptr<u8>; }
8452 if vendor_id == 0x1011 { return "Digital Equipment Corporation" as ptr<u8>; }
8453 if vendor_id == 0x10B7 { return "3Com Corporation" as ptr<u8>; }
8454 if vendor_id == 0x10D9 { return "Macronix, Inc. [MXIC]" as ptr<u8>; }
8455 if vendor_id == 0x1113 { return "Accton Technology Corporation" as ptr<u8>; }
8456 if vendor_id == 0x11AD { return "Lite-On Communications Inc" as ptr<u8>; }
8457 if vendor_id == 0x1259 { return "Allied Telesyn International" as ptr<u8>; }
8458 if vendor_id == 0x1371 { return "Creative Labs" as ptr<u8>; }
8459 if vendor_id == 0x1102 { return "Creative Labs [Audio]" as ptr<u8>; }
8460 if vendor_id == 0x13F6 { return "C-Media Electronics Inc" as ptr<u8>; }
8461 if vendor_id == 0x109E { return "Brooktree Corporation" as ptr<u8>; }
8462 if vendor_id == 0x10CC { return "Ericsson Microelectronics" as ptr<u8>; }
8463 if vendor_id == 0x12D8 { return "Pericom Semiconductor" as ptr<u8>; }
8464 if vendor_id == 0x1B73 { return "Fresco Logic" as ptr<u8>; }
8465 if vendor_id == 0x1912 { return "Renesas Technology Corp." as ptr<u8>; }
8466 if vendor_id == 0x1180 { return "Ricoh Co Ltd" as ptr<u8>; }
8467 if vendor_id == 0x1217 { return "O2 Micro, Inc." as ptr<u8>; }
8468 if vendor_id == 0x1524 { return "ENE Technology Inc" as ptr<u8>; }
8469 if vendor_id == 0x125D { return "ESS Technology" as ptr<u8>; }
8470 if vendor_id == 0x1073 { return "Yamaha Corporation" as ptr<u8>; }
8471 if vendor_id == 0x1039 { return "Silicon Integrated Systems [SiS]" as ptr<u8>; }
8472 if vendor_id == 0x10B9 { return "ULi Electronics Inc." as ptr<u8>; }
8473 if vendor_id == 0x5333 { return "S3 Graphics Ltd." as ptr<u8>; }
8474 return "Unknown Device Vendor" as ptr<u8>;
8475 }
8476 fn get_pci_device_name_ext(vendor_id: u16, device_id: u16) -> ptr<u8> {
8477 if vendor_id == 0x8086 {
8478 if device_id == 0x100E { return "82540EM Gigabit Ethernet Controller" as ptr<u8>; }
8479 if device_id == 0x100F { return "82545EM Gigabit Ethernet Controller" as ptr<u8>; }
8480 if device_id == 0x10D3 { return "82574L Gigabit Network Connection" as ptr<u8>; }
8481 if device_id == 0x10EA { return "82577LM Gigabit Network Connection" as ptr<u8>; }
8482 if device_id == 0x1502 { return "82579LM Gigabit Network Connection" as ptr<u8>; }
8483 if device_id == 0x1503 { return "82579V Gigabit Network Connection" as ptr<u8>; }
8484 if device_id == 0x153A { return "I217-LM Gigabit Network Connection" as ptr<u8>; }
8485 if device_id == 0x153B { return "I217-V Gigabit Network Connection" as ptr<u8>; }
8486 if device_id == 0x15B7 { return "I219-LM Gigabit Network Connection" as ptr<u8>; }
8487 if device_id == 0x15B8 { return "I219-V Gigabit Network Connection" as ptr<u8>; }
8488 if device_id == 0x10FB { return "82599ES 10-Gigabit SFI/SFP+ Network Connection" as ptr<u8>; }
8489 if device_id == 0x1528 { return "Ethernet Controller 10-Gigabit X540-AT2" as ptr<u8>; }
8490 if device_id == 0x2922 { return "82801IR/IO/P (ICH9) 6 port SATA Controller" as ptr<u8>; }
8491 if device_id == 0x1C02 { return "6 Series/C200 Series Chipset Family 6 port SATA" as ptr<u8>; }
8492 if device_id == 0x1E02 { return "7 Series/C210 Series Chipset Family 6-port SATA" as ptr<u8>; }
8493 if device_id == 0x8C02 { return "8 Series/C220 Series Chipset Family 6-port SATA" as ptr<u8>; }
8494 if device_id == 0xA102 { return "100 Series/C230 Series Chipset Family SATA" as ptr<u8>; }
8495 if device_id == 0xA282 { return "200 Series/Z370 Chipset Family SATA AHCI" as ptr<u8>; }
8496 if device_id == 0x0116 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
8497 if device_id == 0x0166 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
8498 if device_id == 0x0412 { return "4th Gen Core Processor Integrated Graphics" as ptr<u8>; }
8499 if device_id == 0x1912 { return "HD Graphics 530" as ptr<u8>; }
8500 if device_id == 0x3E92 { return "UHD Graphics 630 (Desktop)" as ptr<u8>; }
8501 if device_id == 0x9BC5 { return "CometLake-S GT2 [UHD Graphics 630]" as ptr<u8>; }
8502 if device_id == 0x2668 { return "82801FB/FBM/FR/FW/FRW High Definition Audio" as ptr<u8>; }
8503 if device_id == 0x284B { return "82801H (ICH8 Family) High Definition Audio" as ptr<u8>; }
8504 if device_id == 0x293E { return "82801I (ICH9 Family) High Definition Audio" as ptr<u8>; }
8505 if device_id == 0x1E20 { return "7 Series/C210 Series Chipset High Definition Audio" as ptr<u8>; }
8506 if device_id == 0xA170 { return "100 Series/C230 Series Chipset HD Audio" as ptr<u8>; }
8507 if device_id == 0x8C31 { return "8 Series/C220 Series Chipset Family USB xHCI" as ptr<u8>; }
8508 if device_id == 0xA12F { return "100 Series/C230 Series Chipset USB 3.0 xHCI" as ptr<u8>; }
8509 if device_id == 0x1E2D { return "7 Series/C210 Series Chipset USB Enhanced" as ptr<u8>; }
8510 if device_id == 0x24C2 { return "82801DB/DBM (ICH4/ICH4-M) USB UHCI" as ptr<u8>; }
8511 if device_id == 0xF1A5 { return "NVMe SSD Controller (Optane/760p)" as ptr<u8>; }
8512 if device_id == 0x4220 { return "PRO/Wireless 2200BG Network Connection" as ptr<u8>; }
8513 if device_id == 0x4229 { return "PRO/Wireless 4965 AG or AGN Network Connection" as ptr<u8>; }
8514 if device_id == 0x0085 { return "Centrino Advanced-N 6205 [Taylor Peak]" as ptr<u8>; }
8515 if device_id == 0x08B1 { return "Wireless 7260" as ptr<u8>; }
8516 if device_id == 0x24FB { return "Dual Band Wireless-AC 3160" as ptr<u8>; }
8517 if device_id == 0x24FD { return "Dual Band Wireless-AC 8265" as ptr<u8>; }
8518 if device_id == 0x2723 { return "Wi-Fi 6 AX200" as ptr<u8>; }
8519 if device_id == 0x2725 { return "Wi-Fi 6 AX210/AX1675 2x2" as ptr<u8>; }
8520 if device_id == 0x7113 { return "PIIX4/4E/4M IDE Controller" as ptr<u8>; }
8521 if device_id == 0x1237 { return "440FX - 82441FX PMC" as ptr<u8>; }
8522 if device_id == 0x7000 { return "82371SB PIIX3 ISA" as ptr<u8>; }
8523 if device_id == 0x7110 { return "82371AB/EB/MB PIIX4 ISA" as ptr<u8>; }
8524 if device_id == 0x7111 { return "82371AB/EB/MB PIIX4 IDE" as ptr<u8>; }
8525 if device_id == 0x7112 { return "82371AB/EB/MB PIIX4 USB" as ptr<u8>; }
8526 return "Intel Controller" as ptr<u8>;
8527 }
8528 if vendor_id == 0x10EC {
8529 if device_id == 0x8139 { return "RTL-8100/8101L/8139 PCI Fast Ethernet" as ptr<u8>; }
8530 if device_id == 0x8168 { return "RTL8111/8168/8411 PCI Express Gigabit" as ptr<u8>; }
8531 if device_id == 0x8169 { return "RTL8169 PCI Gigabit Ethernet" as ptr<u8>; }
8532 if device_id == 0x8125 { return "RTL8125 2.5GbE Controller" as ptr<u8>; }
8533 if device_id == 0x818B { return "RTL8192EE PCIe Wireless Network Adapter" as ptr<u8>; }
8534 if device_id == 0x8821 { return "RTL8821AE 802.11ac PCIe Wireless" as ptr<u8>; }
8535 if device_id == 0x8822 { return "RTL8822BE 802.11a/b/g/n/ac WiFi" as ptr<u8>; }
8536 if device_id == 0x522A { return "RTS522A PCI Express Card Reader" as ptr<u8>; }
8537 if device_id == 0x0282 { return "RTL8188EE Wireless Network Adapter" as ptr<u8>; }
8538 if device_id == 0x8161 { return "RTL8162 Fast Ethernet" as ptr<u8>; }
8539 if device_id == 0x8167 { return "RTL8167 Gigabit Ethernet" as ptr<u8>; }
8540 if device_id == 0x5209 { return "RTS5209 PCI Express Card Reader" as ptr<u8>; }
8541 if device_id == 0x5227 { return "RTS5227 PCI Express Card Reader" as ptr<u8>; }
8542 if device_id == 0x5289 { return "RTL8411B PCI Express Card Reader" as ptr<u8>; }
8543 return "Realtek Device" as ptr<u8>;
8544 }
8545 if vendor_id == 0x10DE {
8546 if device_id == 0x0402 { return "GeForce 8600 GT" as ptr<u8>; }
8547 if device_id == 0x0611 { return "GeForce 8800 GT" as ptr<u8>; }
8548 if device_id == 0x0A20 { return "GeForce GT 220" as ptr<u8>; }
8549 if device_id == 0x06C0 { return "GeForce GTX 480" as ptr<u8>; }
8550 if device_id == 0x1080 { return "GeForce GTX 580" as ptr<u8>; }
8551 if device_id == 0x1180 { return "GeForce GTX 680" as ptr<u8>; }
8552 if device_id == 0x13C2 { return "GeForce GTX 970" as ptr<u8>; }
8553 if device_id == 0x13C0 { return "GeForce GTX 980" as ptr<u8>; }
8554 if device_id == 0x1C03 { return "GeForce GTX 1060 6GB" as ptr<u8>; }
8555 if device_id == 0x1B81 { return "GeForce GTX 1070" as ptr<u8>; }
8556 if device_id == 0x1B06 { return "GeForce GTX 1080 Ti" as ptr<u8>; }
8557 if device_id == 0x1E84 { return "GeForce RTX 2070" as ptr<u8>; }
8558 if device_id == 0x1E07 { return "GeForce RTX 2080 Ti" as ptr<u8>; }
8559 if device_id == 0x2204 { return "GeForce RTX 3090" as ptr<u8>; }
8560 if device_id == 0x2484 { return "GeForce RTX 3070" as ptr<u8>; }
8561 if device_id == 0x2684 { return "GeForce RTX 4090" as ptr<u8>; }
8562 if device_id == 0x28E0 { return "GeForce RTX 4050 Laptop GPU" as ptr<u8>; }
8563 if device_id == 0x0E0A { return "GF119 HDMI Audio Controller" as ptr<u8>; }
8564 if device_id == 0x0FB0 { return "GM200 High Definition Audio" as ptr<u8>; }
8565 if device_id == 0x10F0 { return "GP104 High Definition Audio" as ptr<u8>; }
8566 if device_id == 0x10FA { return "TU104 HD Audio Controller" as ptr<u8>; }
8567 if device_id == 0x0059 { return "CK804 Serial ATA Controller" as ptr<u8>; }
8568 if device_id == 0x0054 { return "CK804 Memory Controller" as ptr<u8>; }
8569 if device_id == 0x0055 { return "CK804 IDE" as ptr<u8>; }
8570 if device_id == 0x03EF { return "MCP61 Ethernet" as ptr<u8>; }
8571 if device_id == 0x0DF4 { return "GeForce GT 540M" as ptr<u8>; }
8572 if device_id == 0x0FC6 { return "GeForce GTX 650" as ptr<u8>; }
8573 if device_id == 0x1140 { return "GF117M [GeForce 610M/710M]" as ptr<u8>; }
8574 if device_id == 0x139A { return "GM107M [GeForce GTX 950M]" as ptr<u8>; }
8575 if device_id == 0x1C20 { return "GP106M [GeForce GTX 1060 Mobile]" as ptr<u8>; }
8576 if device_id == 0x1F11 { return "TU106M [GeForce RTX 2060 Mobile]" as ptr<u8>; }
8577 if device_id == 0x2520 { return "GA106M [GeForce RTX 3060 Mobile]" as ptr<u8>; }
8578 return "NVIDIA Graphics / Multimedia" as ptr<u8>;
8579 }
8580 if vendor_id == 0x1002 {
8581 if device_id == 0x6738 { return "Radeon HD 6870" as ptr<u8>; }
8582 if device_id == 0x6798 { return "Radeon HD 7970 / R9 280X" as ptr<u8>; }
8583 if device_id == 0x67B1 { return "Radeon R9 290 / 390" as ptr<u8>; }
8584 if device_id == 0x67DF { return "Radeon RX 470/480/570/580/590" as ptr<u8>; }
8585 if device_id == 0x687F { return "Radeon RX Vega 56/64" as ptr<u8>; }
8586 if device_id == 0x731F { return "Radeon RX 5700 XT" as ptr<u8>; }
8587 if device_id == 0x73BF { return "Radeon RX 6800 XT / 6900 XT" as ptr<u8>; }
8588 if device_id == 0x744C { return "Radeon RX 7900 XTX" as ptr<u8>; }
8589 if device_id == 0x4383 { return "SB7x0/SB8x0/SB9x0 High Definition Audio" as ptr<u8>; }
8590 if device_id == 0x1457 { return "Family 17h HD Audio Controller" as ptr<u8>; }
8591 if device_id == 0x4391 { return "SB7x0/SB8x0/SB9x0 SATA [AHCI]" as ptr<u8>; }
8592 if device_id == 0x7901 { return "FCH SATA Controller [AHCI]" as ptr<u8>; }
8593 if device_id == 0x515E { return "Radeon X1300/X1550" as ptr<u8>; }
8594 if device_id == 0x9540 { return "Radeon HD 4350/4550" as ptr<u8>; }
8595 if device_id == 0x68B8 { return "Radeon HD 5770" as ptr<u8>; }
8596 if device_id == 0x6819 { return "Radeon HD 7870" as ptr<u8>; }
8597 if device_id == 0x15D8 { return "Raven Ridge [Radeon Vega Series]" as ptr<u8>; }
8598 if device_id == 0x1636 { return "Renoir [Radeon Vega Series]" as ptr<u8>; }
8599 if device_id == 0x73A5 { return "Navi 22 [Radeon RX 6700/6700 XT]" as ptr<u8>; }
8600 if device_id == 0x7480 { return "Navi 31 [Radeon RX 7900 XT]" as ptr<u8>; }
8601 return "AMD/ATI Display / Multimedia" as ptr<u8>;
8602 }
8603 if vendor_id == 0x1AF4 {
8604 if device_id == 0x1000 { return "VirtIO Network Device" as ptr<u8>; }
8605 if device_id == 0x1001 { return "VirtIO Block Device" as ptr<u8>; }
8606 if device_id == 0x1002 { return "VirtIO Memory Balloon" as ptr<u8>; }
8607 if device_id == 0x1003 { return "VirtIO Console" as ptr<u8>; }
8608 if device_id == 0x1004 { return "VirtIO SCSI" as ptr<u8>; }
8609 if device_id == 0x1005 { return "VirtIO RNG" as ptr<u8>; }
8610 if device_id == 0x1041 { return "VirtIO Network Device (Modern)" as ptr<u8>; }
8611 if device_id == 0x1042 { return "VirtIO Block Device (Modern)" as ptr<u8>; }
8612 if device_id == 0x1050 { return "VirtIO GPU" as ptr<u8>; }
8613 if device_id == 0x1052 { return "VirtIO Input Device" as ptr<u8>; }
8614 if device_id == 0x1053 { return "VirtIO Socket Device" as ptr<u8>; }
8615 return "VirtIO Standard Device" as ptr<u8>;
8616 }
8617 if vendor_id == 0x15AD {
8618 if device_id == 0x0405 { return "VMware SVGA II Adapter" as ptr<u8>; }
8619 if device_id == 0x07B0 { return "VMware VMXNET3 Ethernet" as ptr<u8>; }
8620 if device_id == 0x07A0 { return "VMware PVSCSI SCSI" as ptr<u8>; }
8621 if device_id == 0x0770 { return "VMware USB2 EHCI" as ptr<u8>; }
8622 if device_id == 0x0774 { return "VMware USB1 UHCI" as ptr<u8>; }
8623 return "VMware Virtual Device" as ptr<u8>;
8624 }
8625 if vendor_id == 0x80EE {
8626 if device_id == 0xBEEF { return "VirtualBox Graphics Adapter" as ptr<u8>; }
8627 if device_id == 0xCAFE { return "VirtualBox Guest Service" as ptr<u8>; }
8628 return "VirtualBox Virtual Device" as ptr<u8>;
8629 }
8630 if vendor_id == 0x144D {
8631 if device_id == 0xA802 { return "Samsung SM951 NVMe" as ptr<u8>; }
8632 if device_id == 0xA804 { return "Samsung 960 EVO/PRO NVMe" as ptr<u8>; }
8633 if device_id == 0xA808 { return "Samsung 970 EVO/PRO NVMe" as ptr<u8>; }
8634 if device_id == 0xA80A { return "Samsung 980 PRO NVMe" as ptr<u8>; }
8635 if device_id == 0xA80C { return "Samsung 990 PRO NVMe" as ptr<u8>; }
8636 if device_id == 0xA809 { return "Samsung PM9A1 NVMe" as ptr<u8>; }
8637 return "Samsung NVMe Controller" as ptr<u8>;
8638 }
8639 if vendor_id == 0x14E4 {
8640 if device_id == 0x1659 { return "NetXtreme BCM5721 Gigabit" as ptr<u8>; }
8641 if device_id == 0x1677 { return "NetXtreme BCM5751 Gigabit" as ptr<u8>; }
8642 if device_id == 0x4311 { return "BCM4311 802.11b/g WLAN" as ptr<u8>; }
8643 if device_id == 0x4322 { return "BCM4322 802.11a/b/g/n Wireless" as ptr<u8>; }
8644 if device_id == 0x4360 { return "BCM4360 802.11ac Wireless" as ptr<u8>; }
8645 if device_id == 0x1692 { return "NetLink BCM57780 Gigabit" as ptr<u8>; }
8646 if device_id == 0x4331 { return "BCM4331 802.11a/b/g/n" as ptr<u8>; }
8647 if device_id == 0x43A0 { return "BCM4360 802.11ac Wireless" as ptr<u8>; }
8648 return "Broadcom Communications" as ptr<u8>;
8649 }
8650 if vendor_id == 0x168C {
8651 if device_id == 0x002B { return "AR9285 Wireless Network Adapter" as ptr<u8>; }
8652 if device_id == 0x002E { return "AR9287 Wireless Network Adapter" as ptr<u8>; }
8653 if device_id == 0x0032 { return "AR9485 Wireless Network Adapter" as ptr<u8>; }
8654 if device_id == 0x003C { return "QCA986x/988x 802.11ac Wireless" as ptr<u8>; }
8655 if device_id == 0x0013 { return "AR5212/AR5213 Wireless Network Adapter" as ptr<u8>; }
8656 if device_id == 0x001C { return "AR2424 Wireless Network Adapter" as ptr<u8>; }
8657 if device_id == 0x0030 { return "AR9300 Wireless Network Adapter" as ptr<u8>; }
8658 if device_id == 0x003E { return "QCA6174 802.11ac Wireless" as ptr<u8>; }
8659 if device_id == 0x0042 { return "QCA9377 802.11ac Wireless" as ptr<u8>; }
8660 return "Atheros Wireless Device" as ptr<u8>;
8661 }
8662 if vendor_id == 0x1000 {
8663 if device_id == 0x0054 { return "MegaRAID SAS 2008" as ptr<u8>; }
8664 if device_id == 0x005B { return "MegaRAID SAS 2108" as ptr<u8>; }
8665 if device_id == 0x005D { return "MegaRAID SAS 2208" as ptr<u8>; }
8666 if device_id == 0x005F { return "MegaRAID SAS 3008" as ptr<u8>; }
8667 if device_id == 0x00cf { return "MegaRAID SAS 3108" as ptr<u8>; }
8668 return "LSI Logic Storage Controller" as ptr<u8>;
8669 }
8670 if vendor_id == 0x1102 {
8671 if device_id == 0x0002 { return "Sound Blaster Live! (EMU10K1)" as ptr<u8>; }
8672 if device_id == 0x0004 { return "Sound Blaster Audigy (EMU10K2)" as ptr<u8>; }
8673 if device_id == 0x0005 { return "Sound Blaster X-Fi" as ptr<u8>; }
8674 if device_id == 0x000A { return "Sound Blaster X-Fi Titanium" as ptr<u8>; }
8675 if device_id == 0x0012 { return "Sound Blaster Recon3D" as ptr<u8>; }
8676 return "Creative Audio Device" as ptr<u8>;
8677 }
8678 if vendor_id == 0x1011 {
8679 if device_id == 0x0009 { return "DECchip 21140 [FasterNet]" as ptr<u8>; }
8680 if device_id == 0x0019 { return "DECchip 21142/43" as ptr<u8>; }
8681 return "DEC Ethernet Controller" as ptr<u8>;
8682 }
8683 if vendor_id == 0x10B7 {
8684 if device_id == 0x9050 { return "3c905 100BaseTX" as ptr<u8>; }
8685 if device_id == 0x9055 { return "3c905B 100BaseTX" as ptr<u8>; }
8686 if device_id == 0x9200 { return "3c905C-TX/TX-M" as ptr<u8>; }
8687 return "3Com Fast Ethernet" as ptr<u8>;
8688 }
8689 if vendor_id == 0x11AB {
8690 if device_id == 0x4364 { return "88E8056 PCI-E Gigabit Ethernet" as ptr<u8>; }
8691 if device_id == 0x4380 { return "88E8057 PCI-E Gigabit Ethernet" as ptr<u8>; }
8692 if device_id == 0x9123 { return "88SE9123 PCIe SATA 6.0 Gb/s" as ptr<u8>; }
8693 if device_id == 0x9215 { return "88SE9215 PCIe SATA 6.0 Gb/s" as ptr<u8>; }
8694 return "Marvell Technology Device" as ptr<u8>;
8695 }
8696 if vendor_id == 0x1B21 {
8697 if device_id == 0x0612 { return "ASM1062 Serial ATA Controller" as ptr<u8>; }
8698 if device_id == 0x1042 { return "ASM1042 SuperSpeed USB Host" as ptr<u8>; }
8699 if device_id == 0x1142 { return "ASM1142 USB 3.1 Host" as ptr<u8>; }
8700 if device_id == 0x2142 { return "ASM2142 USB 3.1 Host" as ptr<u8>; }
8701 if device_id == 0x3242 { return "ASM3242 USB 3.2 Host" as ptr<u8>; }
8702 return "ASMedia Host Controller" as ptr<u8>;
8703 }
8704 if vendor_id == 0x1039 {
8705 if device_id == 0x0190 { return "SiS900 PCI Fast Ethernet" as ptr<u8>; }
8706 if device_id == 0x0191 { return "SiS191 Gigabit Ethernet" as ptr<u8>; }
8707 if device_id == 0x0180 { return "SiS180 SATA Controller" as ptr<u8>; }
8708 if device_id == 0x7012 { return "SiS7012 AC'97 Sound" as ptr<u8>; }
8709 if device_id == 0x7001 { return "SiS5597/5598/5600 USB UHCI" as ptr<u8>; }
8710 return "SiS Chipset Component" as ptr<u8>;
8711 }
8712 if vendor_id == 0x1106 {
8713 if device_id == 0x3065 { return "VT6102/VT6103 [Rhine-II]" as ptr<u8>; }
8714 if device_id == 0x3106 { return "VT6105/VT6106S [Rhine-III]" as ptr<u8>; }
8715 if device_id == 0x3119 { return "VT6120/VT6121/VT6122 Velocity Gigabit" as ptr<u8>; }
8716 if device_id == 0x3149 { return "VT6420 SATA RAID" as ptr<u8>; }
8717 if device_id == 0x3249 { return "VT6421 IDE RAID" as ptr<u8>; }
8718 if device_id == 0x0591 { return "VT82C598/694x [Apollo Pro]" as ptr<u8>; }
8719 if device_id == 0x3038 { return "VT82xxxxx UHCI USB 1.1" as ptr<u8>; }
8720 if device_id == 0x3104 { return "USB 2.0" as ptr<u8>; }
8721 if device_id == 0x3288 { return "VT8237A HD Audio Controller" as ptr<u8>; }
8722 if device_id == 0x3059 { return "VT8233/A/8235/8237 AC97 Audio" as ptr<u8>; }
8723 return "VIA Technologies Device" as ptr<u8>;
8724 }
8725 if vendor_id == 0x15B3 {
8726 if device_id == 0x1003 { return "MT27500 Family [ConnectX-3]" as ptr<u8>; }
8727 if device_id == 0x1013 { return "MT27700 Family [ConnectX-4]" as ptr<u8>; }
8728 if device_id == 0x1015 { return "MT27710 Family [ConnectX-4 Lx]" as ptr<u8>; }
8729 if device_id == 0x1017 { return "MT27800 Family [ConnectX-5]" as ptr<u8>; }
8730 if device_id == 0x101B { return "MT28908 Family [ConnectX-6]" as ptr<u8>; }
8731 return "Mellanox Network Adapter" as ptr<u8>;
8732 }
8733 if vendor_id == 0x121A {
8734 if device_id == 0x0001 { return "Voodoo Graphics" as ptr<u8>; }
8735 if device_id == 0x0002 { return "Voodoo 2" as ptr<u8>; }
8736 if device_id == 0x0003 { return "Voodoo Banshee" as ptr<u8>; }
8737 if device_id == 0x0004 { return "Voodoo 3" as ptr<u8>; }
8738 if device_id == 0x0005 { return "Voodoo 4/5" as ptr<u8>; }
8739 return "3Dfx Voodoo Accelerator" as ptr<u8>;
8740 }
8741 if vendor_id == 0x102B {
8742 if device_id == 0x0519 { return "MGA Millennium" as ptr<u8>; }
8743 if device_id == 0x051B { return "MGA Mystique" as ptr<u8>; }
8744 if device_id == 0x0521 { return "MGA G200" as ptr<u8>; }
8745 if device_id == 0x0525 { return "MGA G400/G450" as ptr<u8>; }
8746 if device_id == 0x2527 { return "MGA G550" as ptr<u8>; }
8747 return "Matrox Graphics" as ptr<u8>;
8748 }
8749 if vendor_id == 0x5333 {
8750 if device_id == 0x8811 { return "Trio32/64/64V+" as ptr<u8>; }
8751 if device_id == 0x8A01 { return "ViRGE/DX or /GX" as ptr<u8>; }
8752 if device_id == 0x8A22 { return "Savage 3D" as ptr<u8>; }
8753 if device_id == 0x8C10 { return "Savage/MX" as ptr<u8>; }
8754 if device_id == 0x8D04 { return "Savage4" as ptr<u8>; }
8755 if device_id == 0x8C2E { return "SuperSavage IX/C" as ptr<u8>; }
8756 return "S3 Graphics Device" as ptr<u8>;
8757 }
8758
8759 return "Generic Peripheral Component" as ptr<u8>;
8760 }
8761 struct CpuState {
8762 ds: u16,
8763 es: u16,
8764 fs: u16,
8765 gs: u16,
8766 rax: u64,
8767 rbx: u64,
8768 rcx: u64,
8769 rdx: u64,
8770 rsi: u64,
8771 rdi: u64,
8772 rbp: u64,
8773 r8: u64,
8774 r9: u64,
8775 r10: u64,
8776 r11: u64,
8777 r12: u64,
8778 r13: u64,
8779 r14: u64,
8780 r15: u64,
8781 int_num: u64,
8782 error_code: u64,
8783 rip: u64,
8784 cs: u64,
8785 rflags: u64,
8786 rsp: u64,
8787 ss: u64,
8788 }
8789 fn get_exception_name(vector: u64) -> ptr<u8> {
8790 if vector == 0 { return "Divide By Zero Exception" as ptr<u8>; }
8791 if vector == 1 { return "Debug Exception" as ptr<u8>; }
8792 if vector == 2 { return "Non-maskable Interrupt" as ptr<u8>; }
8793 if vector == 3 { return "Breakpoint Exception" as ptr<u8>; }
8794 if vector == 4 { return "Overflow Exception" as ptr<u8>; }
8795 if vector == 5 { return "Bound Range Exceeded" as ptr<u8>; }
8796 if vector == 6 { return "Invalid Opcode" as ptr<u8>; }
8797 if vector == 7 { return "Device Not Available" as ptr<u8>; }
8798 if vector == 8 { return "Double Fault" as ptr<u8>; }
8799 if vector == 9 { return "Coprocessor Segment Overrun" as ptr<u8>; }
8800 if vector == 10 { return "Invalid TSS" as ptr<u8>; }
8801 if vector == 11 { return "Segment Not Present" as ptr<u8>; }
8802 if vector == 12 { return "Stack-Segment Fault" as ptr<u8>; }
8803 if vector == 13 { return "General Protection Fault" as ptr<u8>; }
8804 if vector == 14 { return "Page Fault" as ptr<u8>; }
8805 if vector == 15 { return "Reserved" as ptr<u8>; }
8806 if vector == 16 { return "x87 Floating-Point Exception" as ptr<u8>; }
8807 if vector == 17 { return "Alignment Check" as ptr<u8>; }
8808 if vector == 18 { return "Machine Check" as ptr<u8>; }
8809 if vector == 19 { return "SIMD Floating-Point Exception" as ptr<u8>; }
8810 if vector == 20 { return "Virtualization Exception" as ptr<u8>; }
8811 if vector == 21 { return "Control Protection Exception" as ptr<u8>; }
8812 if vector == 28 { return "Hypervisor Injection Exception" as ptr<u8>; }
8813 if vector == 29 { return "VMM Communication Exception" as ptr<u8>; }
8814 if vector == 30 { return "Security Exception" as ptr<u8>; }
8815 return "Unknown Interrupt/Exception" as ptr<u8>;
8816 }
8817 fn render_panic_screen(state: ptr<CpuState>, cr2: u64, cr3: u64) {
8818 panic_clear_screen(VGA_COLOR_WHITE_ON_RED);
8819
8820 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
8821 panic_write_padded_string(" W KERNEL PANIC - CRITICAL SYSTEM HALT " as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8822 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
8823
8824 panic_print_string("\nEXCEPTION: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8825 let ext_name = get_exception_name((*state).int_num);
8826 panic_print_string(ext_name, VGA_COLOR_WHITE_ON_RED);
8827 panic_print_string(" (" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8828 panic_print_hex((*state).int_num, VGA_COLOR_WHITE_ON_RED);
8829 panic_print_string(")\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8830
8831 panic_print_string("ERROR CODE: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8832 panic_print_hex((*state).error_code, VGA_COLOR_WHITE_ON_RED);
8833 panic_print_string("\n\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8834
8835 panic_write_padded_string("--- CPU REGISTERS ---" as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8836 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8837
8838 panic_print_string("RAX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8839 panic_print_hex((*state).rax, VGA_COLOR_WHITE_ON_RED);
8840 panic_print_string(" RBX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8841 panic_print_hex((*state).rbx, VGA_COLOR_WHITE_ON_RED);
8842 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8843
8844 panic_print_string("RCX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8845 panic_print_hex((*state).rcx, VGA_COLOR_WHITE_ON_RED);
8846 panic_print_string(" RDX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8847 panic_print_hex((*state).rdx, VGA_COLOR_WHITE_ON_RED);
8848 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8849
8850 panic_print_string("RSI: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8851 panic_print_hex((*state).rsi, VGA_COLOR_WHITE_ON_RED);
8852 panic_print_string(" RDI: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8853 panic_print_hex((*state).rdi, VGA_COLOR_WHITE_ON_RED);
8854 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8855
8856 panic_print_string("RBP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8857 panic_print_hex((*state).rbp, VGA_COLOR_WHITE_ON_RED);
8858 panic_print_string(" RSP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8859 panic_print_hex((*state).rsp, VGA_COLOR_WHITE_ON_RED);
8860 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8861
8862 panic_print_string("R8 : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8863 panic_print_hex((*state).r8, VGA_COLOR_WHITE_ON_RED);
8864 panic_print_string(" R9 : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8865 panic_print_hex((*state).r9, VGA_COLOR_WHITE_ON_RED);
8866 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8867
8868 panic_print_string("R10: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8869 panic_print_hex((*state).r10, VGA_COLOR_WHITE_ON_RED);
8870 panic_print_string(" R11: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8871 panic_print_hex((*state).r11, VGA_COLOR_WHITE_ON_RED);
8872 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8873
8874 panic_print_string("R12: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8875 panic_print_hex((*state).r12, VGA_COLOR_WHITE_ON_RED);
8876 panic_print_string(" R13: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8877 panic_print_hex((*state).r13, VGA_COLOR_WHITE_ON_RED);
8878 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8879
8880 panic_print_string("R14: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8881 panic_print_hex((*state).r14, VGA_COLOR_WHITE_ON_RED);
8882 panic_print_string(" R15: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8883 panic_print_hex((*state).r15, VGA_COLOR_WHITE_ON_RED);
8884 panic_print_string("\n\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8885
8886 panic_write_padded_string("--- CONTROL REGISTERS & SEGMENTS ---" as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8887 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8888
8889 panic_print_string("RIP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8890 panic_print_hex((*state).rip, VGA_COLOR_WHITE_ON_RED);
8891 panic_print_string(" RFL: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8892 panic_print_hex((*state).rflags, VGA_COLOR_WHITE_ON_RED);
8893 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8894
8895 panic_print_string("CR2: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8896 panic_print_hex(cr2, VGA_COLOR_WHITE_ON_RED);
8897 panic_print_string(" CR3: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8898 panic_print_hex(cr3, VGA_COLOR_WHITE_ON_RED);
8899 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8900
8901 panic_print_string("CS : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8902 panic_print_hex((*state).cs as u64, VGA_COLOR_WHITE_ON_RED);
8903 panic_print_string(" SS : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8904 panic_print_hex((*state).ss as u64, VGA_COLOR_WHITE_ON_RED);
8905 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8906 }
8907 fn dump_stack_trace(rbp: u64, max_frames: u64) {
8908 panic_print_string("\n--- STACK TRACE ---\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8909 let mut current_rbp = rbp;
8910 let mut frame_count: u64 = 0;
8911
8912 while current_rbp != 0 {
8913 if frame_count >= max_frames {
8914 break;
8915 }
8916
8917 let rip_ptr = (current_rbp + 8) as ptr<u64>;
8918 let rip = *rip_ptr;
8919
8920 if rip == 0 {
8921 break;
8922 }
8923
8924 panic_print_string(" [" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8925 panic_print_hex(frame_count, VGA_COLOR_WHITE_ON_RED);
8926 panic_print_string("] " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8927 panic_print_hex(rip, VGA_COLOR_WHITE_ON_RED);
8928 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8929
8930 let next_rbp_ptr = current_rbp as ptr<u64>;
8931 current_rbp = *next_rbp_ptr;
8932 frame_count = frame_count + 1;
8933 }
8934 }
8935 fn kernel_panic_handler(state: ptr<CpuState>) {
8936 let cr2_val: u64 = 0;
8937 let cr3_val: u64 = 0;
8938
8939 render_panic_screen(state, cr2_val, cr3_val);
8940 dump_stack_trace((*state).rbp, 8);
8941
8942 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
8943 panic_print_string("SYSTEM HALTED." as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8944
8945 while true {}
8946 }
8947 struct IdtEntry {
8948 base_low: u16,
8949 sel: u16,
8950 ist: u8,
8951 flags: u8,
8952 base_mid: u16,
8953 base_high: u32,
8954 reserved: u32,
8955 }
8956 struct IdtPtr {
8957 limit: u16,
8958 base: u64,
8959 }
8960 let mut idt: [IdtEntry; 256];
8961 let mut idtp: IdtPtr;
8962 fn idt_set_gate(num: u8, base: u64, sel: u16, flags: u8) {
8963 let index = num as usize;
8964 idt[index].base_low = (base & 0xFFFF) as u16;
8965 idt[index].base_mid = ((base >> 16) & 0xFFFF) as u16;
8966 idt[index].base_high = (base >> 32) as u32;
8967 idt[index].sel = sel;
8968 idt[index].ist = 0;
8969 idt[index].flags = flags;
8970 idt[index].reserved = 0;
8971 }
8972 fn idt_install() {
8973 idtp.limit = (256 * 16) - 1;
8974 idtp.base = &idt[0] as ptr<IdtEntry> as u64;
8975 let mut i: u64 = 0;
8976 while i < 256 {
8977 idt_set_gate(i as u8, 0, 0x08, 0x8E);
8978 i = i + 1;
8979 }
8980 }
8981 fn fault_divide_error(state: ptr<CpuState>) { kernel_panic_handler(state); }
8982 fn fault_debug(state: ptr<CpuState>) { kernel_panic_handler(state); }
8983 fn fault_nmi(state: ptr<CpuState>) { kernel_panic_handler(state); }
8984 fn fault_breakpoint(state: ptr<CpuState>) { kernel_panic_handler(state); }
8985 fn fault_overflow(state: ptr<CpuState>) { kernel_panic_handler(state); }
8986 fn fault_bounds(state: ptr<CpuState>) { kernel_panic_handler(state); }
8987 fn fault_invalid_opcode(state: ptr<CpuState>) { kernel_panic_handler(state); }
8988 fn fault_device_not_available(state: ptr<CpuState>) { kernel_panic_handler(state); }
8989 fn fault_double_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
8990 fn fault_coproc_segment_overrun(state: ptr<CpuState>) { kernel_panic_handler(state); }
8991 fn fault_invalid_tss(state: ptr<CpuState>) { kernel_panic_handler(state); }
8992 fn fault_segment_not_present(state: ptr<CpuState>) { kernel_panic_handler(state); }
8993 fn fault_stack_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
8994 fn fault_general_protection(state: ptr<CpuState>) { kernel_panic_handler(state); }
8995 fn fault_page_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
8996 fn fault_x87_fpu(state: ptr<CpuState>) { kernel_panic_handler(state); }
8997 fn fault_alignment_check(state: ptr<CpuState>) { kernel_panic_handler(state); }
8998 fn fault_machine_check(state: ptr<CpuState>) { kernel_panic_handler(state); }
8999 fn fault_simd_fpu(state: ptr<CpuState>) { kernel_panic_handler(state); }
9000 fn fault_virtualization(state: ptr<CpuState>) { kernel_panic_handler(state); }
9001 struct Process {
9002 pid: u64,
9003 rsp: u64,
9004 rip: u64,
9005 cr3: u64,
9006 state: u8,
9007 time_slice: u64,
9008 }
9009 let mut process_table: [Process; 256];
9010 let mut current_pid: u64 = 0;
9011 let mut total_processes: u64 = 0;
9012 fn scheduler_init() {
9013 let mut i: u64 = 0;
9014 while i < 256 {
9015 process_table[i as usize].pid = 0;
9016 process_table[i as usize].state = 0;
9017 i = i + 1;
9018 }
9019 }
9020 fn process_create(entry_point: u64, stack_pointer: u64, page_dir: u64) -> u64 {
9021 if total_processes >= 256 {
9022 return 0;
9023 }
9024
9025 let pid = total_processes + 1;
9026 let index = total_processes as usize;
9027
9028 process_table[index].pid = pid;
9029 process_table[index].rip = entry_point;
9030 process_table[index].rsp = stack_pointer;
9031 process_table[index].cr3 = page_dir;
9032 process_table[index].state = 1;
9033 process_table[index].time_slice = 15;
9034
9035 total_processes = total_processes + 1;
9036 return pid;
9037 }
9038 fn schedule_next(current_rsp: u64) -> u64 {
9039 if total_processes == 0 {
9040 return current_rsp;
9041 }
9042 if current_pid > 0 {
9043 let curr_idx = (current_pid - 1) as usize;
9044 process_table[curr_idx].rsp = current_rsp;
9045
9046 if process_table[curr_idx].time_slice > 0 {
9047 process_table[curr_idx].time_slice = process_table[curr_idx].time_slice - 1;
9048 if process_table[curr_idx].time_slice > 0 {
9049 return current_rsp;
9050 }
9051 }
9052 process_table[curr_idx].time_slice = 15;
9053 }
9054 current_pid = current_pid + 1;
9055 if current_pid > total_processes {
9056 current_pid = 1;
9057 }
9058 let next_idx = (current_pid - 1) as usize;
9059 return process_table[next_idx].rsp;
9060 }
9061 fn timer_phase(hz: u32) {
9062 let divisor = 1193180 / hz;
9063 outb(0x43, 0x36);
9064 outb(0x40, (divisor & 0xFF) as u8);
9065 outb(0x40, ((divisor >> 8) & 0xFF) as u8);
9066 }
9067 let mut timer_ticks: u64 = 0;
9068 fn timer_handler(state: ptr<CpuState>) -> u64 {
9069 timer_ticks = timer_ticks + 1;
9070 let next_rsp = schedule_next((*state).rsp);
9071 outb(0x20, 0x20);
9072 return next_rsp;
9073 }
9074 let mut memory_bitmap: [u64; 32768];
9075 let mut total_memory_pages: u64 = 0;
9076 let mut used_memory_pages: u64 = 0;
9077 fn set_bit(bitmap: ptr<u64>, index: u64) {
9078 let array_index = index / 64;
9079 let bit_index = index % 64;
9080 let current = *(bitmap + array_index);
9081 *(bitmap + array_index) = current | (1 << bit_index);
9082 }
9083 fn clear_bit(bitmap: ptr<u64>, index: u64) {
9084 let array_index = index / 64;
9085 let bit_index = index % 64;
9086 let current = *(bitmap + array_index);
9087 *(bitmap + array_index) = current & !(1 << bit_index);
9088 }
9089 fn test_bit(bitmap: ptr<u64>, index: u64) -> u64 {
9090 let array_index = index / 64;
9091 let bit_index = index % 64;
9092 let current = *(bitmap + array_index);
9093 if (current & (1 << bit_index)) != 0 {
9094 return 1;
9095 }
9096 return 0;
9097 }
9098 fn pmm_init(mem_size_kb: u64) {
9099 total_memory_pages = (mem_size_kb * 1024) / 4096;
9100 used_memory_pages = 0;
9101 let mut i: u64 = 0;
9102 while i < 32768 {
9103 memory_bitmap[i as usize] = 0;
9104 i = i + 1;
9105 }
9106 }
9107 fn pmm_alloc_page() -> u64 {
9108 let mut i: u64 = 0;
9109 while i < total_memory_pages {
9110 if test_bit(&memory_bitmap[0] as ptr<u64>, i) == 0 {
9111 set_bit(&memory_bitmap[0] as ptr<u64>, i);
9112 used_memory_pages = used_memory_pages + 1;
9113 return i * 4096;
9114 }
9115 i = i + 1;
9116 }
9117 return 0;
9118 }
9119 fn pmm_free_page(addr: u64) {
9120 let page_index = addr / 4096;
9121 clear_bit(&memory_bitmap[0] as ptr<u64>, page_index);
9122 used_memory_pages = used_memory_pages - 1;
9123 }
9124 fn tlb_flush_single(addr: u64) {
9125 asm {
9126 "invlpg [%0]"
9127 :
9128 : "r" (addr)
9129 : "memory"
9130 }
9131 }
9132 fn tlb_flush_all() {
9133 let mut cr3_val: u64 = 0;
9134 asm {
9135 "mov %0, cr3"
9136 "mov cr3, %0"
9137 : "=r" (cr3_val)
9138 :
9139 : "memory"
9140 }
9141 }
9142 fn read_cr3() -> u64 {
9143 let mut cr3_val: u64 = 0;
9144 asm {
9145 "mov %0, cr3"
9146 : "=r" (cr3_val)
9147 }
9148 return cr3_val;
9149 }
9150 fn write_cr3(val: u64) {
9151 asm {
9152 "mov cr3, %0"
9153 :
9154 : "r" (val)
9155 : "memory"
9156 }
9157 }
9158 fn map_page(phys: u64, virt: u64, flags: u64) {
9159 let pml4_index = (virt >> 39) & 0x1FF;
9160 let pdpt_index = (virt >> 30) & 0x1FF;
9161 let pd_index = (virt >> 21) & 0x1FF;
9162 let pt_index = (virt >> 12) & 0x1FF;
9163 let pml4 = read_cr3() as ptr<u64>;
9164 let mut pdpt_entry = *(pml4 + pml4_index);
9165
9166 if (pdpt_entry & 1) == 0 {
9167 let new_pdpt = pmm_alloc_page();
9168 *(pml4 + pml4_index) = new_pdpt | 3;
9169 pdpt_entry = new_pdpt | 3;
9170 }
9171
9172 let pdpt = (pdpt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9173 let mut pd_entry = *(pdpt + pdpt_index);
9174
9175 if (pd_entry & 1) == 0 {
9176 let new_pd = pmm_alloc_page();
9177 *(pdpt + pdpt_index) = new_pd | 3;
9178 pd_entry = new_pd | 3;
9179 }
9180
9181 let pd = (pd_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9182 let mut pt_entry = *(pd + pd_index);
9183
9184 if (pt_entry & 1) == 0 {
9185 let new_pt = pmm_alloc_page();
9186 *(pd + pd_index) = new_pt | 3;
9187 pt_entry = new_pt | 3;
9188 }
9189
9190 let pt = (pt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9191 *(pt + pt_index) = (phys & 0xFFFFFFFFFFFFF000) | (flags & 0xFFF) | 1;
9192
9193 tlb_flush_single(virt);
9194 }
9195 fn unmap_page(virt: u64) {
9196 let pml4_index = (virt >> 39) & 0x1FF;
9197 let pdpt_index = (virt >> 30) & 0x1FF;
9198 let pd_index = (virt >> 21) & 0x1FF;
9199 let pt_index = (virt >> 12) & 0x1FF;
9200 let pml4 = read_cr3() as ptr<u64>;
9201 let pdpt_entry = *(pml4 + pml4_index);
9202
9203 if (pdpt_entry & 1) == 0 { return; }
9204
9205 let pdpt = (pdpt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9206 let pd_entry = *(pdpt + pdpt_index);
9207
9208 if (pd_entry & 1) == 0 { return; }
9209
9210 let pd = (pd_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9211 let pt_entry = *(pd + pd_index);
9212
9213 if (pt_entry & 1) == 0 { return; }
9214
9215 let pt = (pt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
9216 *(pt + pt_index) = 0;
9217
9218 tlb_flush_single(virt);
9219 }
9220 struct HeapBlock {
9221 size: u64,
9222 free: u64,
9223 next: u64,
9224 }
9225 let mut heap_start: u64 = 0;
9226 let mut heap_end: u64 = 0;
9227 let mut heap_head: u64 = 0;
9228 fn heap_init(start_addr: u64, initial_size: u64) {
9229 heap_start = start_addr;
9230 heap_end = start_addr + initial_size;
9231
9232 let mut current_addr = heap_start;
9233 while current_addr < heap_end {
9234 let phys = pmm_alloc_page();
9235 map_page(phys, current_addr, 3);
9236 current_addr = current_addr + 4096;
9237 }
9238
9239 heap_head = heap_start;
9240 let first_block = heap_head as ptr<HeapBlock>;
9241 (*first_block).size = initial_size - 24;
9242 (*first_block).free = 1;
9243 (*first_block).next = 0;
9244 }
9245 fn kmalloc(size: u64) -> u64 {
9246 let mut current = heap_head as ptr<HeapBlock>;
9247 let mut best_fit = 0 as ptr<HeapBlock>;
9248
9249 let mut aligned_size = size;
9250 if (aligned_size % 8) != 0 {
9251 aligned_size = aligned_size + (8 - (aligned_size % 8));
9252 }
9253
9254 while (current as u64) != 0 {
9255 if (*current).free == 1 && (*current).size >= aligned_size {
9256 if (best_fit as u64) == 0 {
9257 best_fit = current;
9258 } else {
9259 if (*current).size < (*best_fit).size {
9260 best_fit = current;
9261 }
9262 }
9263 }
9264 current = (*current).next as ptr<HeapBlock>;
9265 }
9266
9267 if (best_fit as u64) != 0 {
9268 let remaining_size = (*best_fit).size - aligned_size;
9269
9270 if remaining_size > 32 {
9271 let new_block_addr = (best_fit as u64) + 24 + aligned_size;
9272 let new_block = new_block_addr as ptr<HeapBlock>;
9273 (*new_block).size = remaining_size - 24;
9274 (*new_block).free = 1;
9275 (*new_block).next = (*best_fit).next;
9276
9277 (*best_fit).size = aligned_size;
9278 (*best_fit).next = new_block_addr;
9279 }
9280
9281 (*best_fit).free = 0;
9282 return (best_fit as u64) + 24;
9283 }
9284
9285 return 0;
9286 }
9287 fn kfree(ptr: u64) {
9288 if ptr == 0 { return; }
9289
9290 let block_addr = ptr - 24;
9291 let block = block_addr as ptr<HeapBlock>;
9292 (*block).free = 1;
9293
9294 let mut current = heap_head as ptr<HeapBlock>;
9295 while (current as u64) != 0 {
9296 if (*current).free == 1 {
9297 let next_addr = (*current).next;
9298 if next_addr != 0 {
9299 let next_block = next_addr as ptr<HeapBlock>;
9300 if (*next_block).free == 1 {
9301 (*current).size = (*current).size + 24 + (*next_block).size;
9302 (*current).next = (*next_block).next;
9303 continue;
9304 }
9305 }
9306 }
9307 current = (*current).next as ptr<HeapBlock>;
9308 }
9309 }
9310 fn wrmsr(msr: u32, val: u64) {
9311 let low = (val & 0xFFFFFFFF) as u32;
9312 let high = (val >> 32) as u32;
9313 asm {
9314 "wrmsr"
9315 :
9316 : "c" (msr), "a" (low), "d" (high)
9317 : "memory"
9318 }
9319 }
9320 fn rdmsr(msr: u32) -> u64 {
9321 let mut low: u32 = 0;
9322 let mut high: u32 = 0;
9323 asm {
9324 "rdmsr"
9325 : "=a" (low), "=d" (high)
9326 : "c" (msr)
9327 }
9328 return ((high as u64) << 32) | (low as u64);
9329 }
9330 fn syscall_init() {
9331 let star_val = (0x08 << 32) | (0x1B << 48);
9332 wrmsr(0xC0000081, star_val);
9333
9334 let lstar_val = syscall_handler_entry as u64;
9335 wrmsr(0xC0000082, lstar_val);
9336
9337 let fmask_val = 0x200;
9338 wrmsr(0xC0000084, fmask_val);
9339
9340 let efer = rdmsr(0xC0000080);
9341 wrmsr(0xC0000080, efer | 1);
9342 }
9343 fn syscall_handler_entry() {
9344 asm {
9345 "swapgs"
9346 "mov gs:[0], rsp"
9347 "mov rsp, gs:[8]"
9348
9349 "push rcx"
9350 "push r11"
9351
9352 "push rdi"
9353 "push rsi"
9354 "push rdx"
9355 "push r10"
9356 "push r8"
9357 "push r9"
9358
9359 "call syscall_dispatcher"
9360
9361 "pop r9"
9362 "pop r8"
9363 "pop r10"
9364 "pop rdx"
9365 "pop rsi"
9366 "pop rdi"
9367
9368 "pop r11"
9369 "pop rcx"
9370
9371 "mov rsp, gs:[0]"
9372 "swapgs"
9373 "sysretq"
9374 }
9375 }
9376 fn syscall_dispatcher(sys_num: u64, arg1: u64, arg2: u64, arg3: u64) -> u64 {
9377 if sys_num == 1 {
9378 return sys_write(arg1, arg2, arg3);
9379 }
9380 if sys_num == 2 {
9381 return sys_read(arg1, arg2, arg3);
9382 }
9383 if sys_num == 3 {
9384 return sys_exit(arg1);
9385 }
9386 if sys_num == 4 {
9387 return sys_mmap(arg1, arg2);
9388 }
9389 return 0;
9390 }
9391 fn sys_write(fd: u64, buf: u64, count: u64) -> u64 {
9392 if fd == 1 {
9393 let mut i: u64 = 0;
9394 let p = buf as ptr<u8>;
9395 while i < count {
9396 panic_put_char(*(p + i), 0x0F, panic_screen_cursor_x, panic_screen_cursor_y);
9397 panic_screen_cursor_x = panic_screen_cursor_x + 1;
9398 if panic_screen_cursor_x >= 80 {
9399 panic_screen_cursor_x = 0;
9400 panic_screen_cursor_y = panic_screen_cursor_y + 1;
9401 }
9402 i = i + 1;
9403 }
9404 return count;
9405 }
9406 return 0;
9407 }
9408 fn sys_read(fd: u64, buf: u64, count: u64) -> u64 {
9409 return 0;
9410 }
9411 fn sys_exit(code: u64) -> u64 {
9412 let curr_pid = current_pid;
9413 let idx = (curr_pid - 1) as usize;
9414 process_table[idx].state = 0;
9415 while true { asm { "hlt" } }
9416 return 0;
9417 }
9418 fn sys_mmap(addr: u64, len: u64) -> u64 {
9419 let pages = len / 4096 + 1;
9420 let mut i: u64 = 0;
9421 while i < pages {
9422 let phys = pmm_alloc_page();
9423 map_page(phys, addr + (i * 4096), 7);
9424 i = i + 1;
9425 }
9426 return addr;
9427 }
9428 fn switch_to_user_mode(entry_point: u64, user_stack: u64) {
9429 asm {
9430 "cli"
9431 "mov ax, 0x23"
9432 "mov ds, ax"
9433 "mov es, ax"
9434 "mov fs, ax"
9435 "mov gs, ax"
9436
9437 "push 0x23"
9438 "push %1"
9439
9440 "push 0x202"
9441
9442 "push 0x1B"
9443 "push %0"
9444
9445 "iretq"
9446 :
9447 : "r" (entry_point), "r" (user_stack)
9448 : "memory"
9449 }
9450 }
9451 fn init_user_process(code_ptr: u64, code_size: u64) {
9452 let user_stack_virt = 0x00007FFFFFFFF000;
9453 let stack_phys = pmm_alloc_page();
9454 map_page(stack_phys, user_stack_virt, 7);
9455
9456 let user_code_virt = 0x0000000000400000;
9457 let code_phys = pmm_alloc_page();
9458 map_page(code_phys, user_code_virt, 7);
9459
9460 let dest = user_code_virt as ptr<u8>;
9461 let src = code_ptr as ptr<u8>;
9462 let mut i: u64 = 0;
9463 while i < code_size {
9464 *(dest + i) = *(src + i);
9465 i = i + 1;
9466 }
9467
9468 switch_to_user_mode(user_code_virt, user_stack_virt + 4096);
9469 }
9470 fn cpuid(leaf: u32, eax: ptr<u32>, ebx: ptr<u32>, ecx: ptr<u32>, edx: ptr<u32>) {
9471 let mut a: u32 = 0;
9472 let mut b: u32 = 0;
9473 let mut c: u32 = 0;
9474 let mut d: u32 = 0;
9475 asm {
9476 "cpuid"
9477 : "=a" (a), "=b" (b), "=c" (c), "=d" (d)
9478 : "a" (leaf)
9479 }
9480 *eax = a;
9481 *ebx = b;
9482 *ecx = c;
9483 *edx = d;
9484 }
9485 fn inb(port: u16) -> u8 {
9486 let mut ret: u8 = 0;
9487 asm {
9488 "in al, dx"
9489 : "=a" (ret)
9490 : "d" (port)
9491 }
9492 return ret;
9493 }
9494 fn io_wait() {
9495 outb(0x80, 0);
9496 }
9497 fn pic_remap(offset1: u8, offset2: u8) {
9498 let a1 = inb(0x21);
9499 let a2 = inb(0xA1);
9500
9501 outb(0x20, 0x11);
9502 io_wait();
9503 outb(0xA0, 0x11);
9504 io_wait();
9505
9506 outb(0x21, offset1);
9507 io_wait();
9508 outb(0xA1, offset2);
9509 io_wait();
9510
9511 outb(0x21, 4);
9512 io_wait();
9513 outb(0xA1, 2);
9514 io_wait();
9515
9516 outb(0x21, 0x01);
9517 io_wait();
9518 outb(0xA1, 0x01);
9519 io_wait();
9520
9521 outb(0x21, a1);
9522 outb(0xA1, a2);
9523 }
9524 fn outl(port: u16, data: u32) {
9525 asm {
9526 "out dx, eax"
9527 :
9528 : "a" (data), "d" (port)
9529 }
9530 }
9531 fn inl(port: u16) -> u32 {
9532 let mut ret: u32 = 0;
9533 asm {
9534 "in eax, dx"
9535 : "=a" (ret)
9536 : "d" (port)
9537 }
9538 return ret;
9539 }
9540 fn outw(port: u16, data: u16) {
9541 asm {
9542 "out dx, ax"
9543 :
9544 : "a" (data), "d" (port)
9545 }
9546 }
9547 fn pci_config_read_word(bus: u8, slot: u8, func: u8, offset: u8) -> u16 {
9548 let lbus = bus as u32;
9549 let lslot = slot as u32;
9550 let lfunc = func as u32;
9551 let tmp = 0x80000000 | (lbus << 16) | (lslot << 11) | (lfunc << 8) | ((offset as u32) & 0xFC);
9552 outl(0xCF8, tmp);
9553 let shift = ((offset & 2) * 8) as u32;
9554 let read_val = inl(0xCFC);
9555 return ((read_val >> shift) & 0xFFFF) as u16;
9556 }
9557 fn pci_config_read_dword(bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
9558 let lbus = bus as u32;
9559 let lslot = slot as u32;
9560 let lfunc = func as u32;
9561 let tmp = 0x80000000 | (lbus << 16) | (lslot << 11) | (lfunc << 8) | ((offset as u32) & 0xFC);
9562 outl(0xCF8, tmp);
9563 return inl(0xCFC);
9564 }
9565 fn pci_check_vendor(bus: u8, slot: u8) -> u16 {
9566 return pci_config_read_word(bus, slot, 0, 0);
9567 }
9568 struct PciDevice {
9569 bus: u8,
9570 slot: u8,
9571 func: u8,
9572 vendor_id: u16,
9573 device_id: u16,
9574 class_id: u8,
9575 subclass_id: u8,
9576 prog_if: u8,
9577 rev_id: u8,
9578 bar0: u32,
9579 bar1: u32,
9580 bar2: u32,
9581 bar3: u32,
9582 bar4: u32,
9583 bar5: u32,
9584 }
9585 let mut pci_device_list: [PciDevice; 256];
9586 let mut pci_device_count: u64 = 0;
9587 fn pci_add_device(bus: u8, slot: u8, func: u8) {
9588 if pci_device_count >= 256 { return; }
9589 let vendor = pci_config_read_word(bus, slot, func, 0);
9590 if vendor == 0xFFFF { return; }
9591 let device = pci_config_read_word(bus, slot, func, 2);
9592 let class_word = pci_config_read_word(bus, slot, func, 0x0A);
9593 let class_id = (class_word >> 8) as u8;
9594 let subclass_id = (class_word & 0xFF) as u8;
9595
9596 let prog_word = pci_config_read_word(bus, slot, func, 0x08);
9597 let prog_if = (prog_word >> 8) as u8;
9598 let rev_id = (prog_word & 0xFF) as u8;
9599 let b0 = pci_config_read_dword(bus, slot, func, 0x10);
9600 let b1 = pci_config_read_dword(bus, slot, func, 0x14);
9601 let b2 = pci_config_read_dword(bus, slot, func, 0x18);
9602 let b3 = pci_config_read_dword(bus, slot, func, 0x1C);
9603 let b4 = pci_config_read_dword(bus, slot, func, 0x20);
9604 let b5 = pci_config_read_dword(bus, slot, func, 0x24);
9605 let idx = pci_device_count as usize;
9606 pci_device_list[idx].bus = bus;
9607 pci_device_list[idx].slot = slot;
9608 pci_device_list[idx].func = func;
9609 pci_device_list[idx].vendor_id = vendor;
9610 pci_device_list[idx].device_id = device;
9611 pci_device_list[idx].class_id = class_id;
9612 pci_device_list[idx].subclass_id = subclass_id;
9613 pci_device_list[idx].prog_if = prog_if;
9614 pci_device_list[idx].rev_id = rev_id;
9615 pci_device_list[idx].bar0 = b0;
9616 pci_device_list[idx].bar1 = b1;
9617 pci_device_list[idx].bar2 = b2;
9618 pci_device_list[idx].bar3 = b3;
9619 pci_device_list[idx].bar4 = b4;
9620 pci_device_list[idx].bar5 = b5;
9621 pci_device_count = pci_device_count + 1;
9622 }
9623 fn pci_scan_bus() {
9624 let mut bus: u64 = 0;
9625 while bus < 256 {
9626 let mut slot: u64 = 0;
9627 while slot < 32 {
9628 let vendor = pci_check_vendor(bus as u8, slot as u8);
9629 if vendor != 0xFFFF {
9630 let mut func: u64 = 0;
9631 while func < 8 {
9632 let f_vendor = pci_config_read_word(bus as u8, slot as u8, func as u8, 0);
9633 if f_vendor != 0xFFFF {
9634 pci_add_device(bus as u8, slot as u8, func as u8);
9635 }
9636 func = func + 1;
9637 }
9638 }
9639 slot = slot + 1;
9640 }
9641 bus = bus + 1;
9642 }
9643 }
9644 struct VfsNode {
9645 name: [u8; 64],
9646 inode: u64,
9647 size: u64,
9648 flags: u32,
9649 uid: u32,
9650 gid: u32,
9651 read_ptr: u64,
9652 write_ptr: u64,
9653 open_ptr: u64,
9654 close_ptr: u64,
9655 read_dir_ptr: u64,
9656 find_dir_ptr: u64,
9657 parent: u64,
9658 sibling: u64,
9659 child: u64,
9660 }
9661 let mut vfs_nodes: [VfsNode; 1024];
9662 let mut vfs_node_count: u64 = 0;
9663 let mut vfs_root: u64 = 0;
9664 fn vfs_init() {
9665 vfs_node_count = 1;
9666 vfs_root = 0;
9667 let root_idx = vfs_root as usize;
9668 vfs_nodes[root_idx].name[0] = 47;
9669 vfs_nodes[root_idx].name[1] = 0;
9670 vfs_nodes[root_idx].inode = 0;
9671 vfs_nodes[root_idx].size = 0;
9672 vfs_nodes[root_idx].flags = 2;
9673 vfs_nodes[root_idx].parent = 0;
9674 vfs_nodes[root_idx].sibling = 0;
9675 vfs_nodes[root_idx].child = 0;
9676 }
9677 fn strcmp(s1: ptr<u8>, s2: ptr<u8>) -> u64 {
9678 let mut i: u64 = 0;
9679 while *(s1 + i) != 0 && *(s2 + i) != 0 {
9680 if *(s1 + i) != *(s2 + i) {
9681 return 1;
9682 }
9683 i = i + 1;
9684 }
9685 if *(s1 + i) != *(s2 + i) {
9686 return 1;
9687 }
9688 return 0;
9689 }
9690 fn strcpy(dest: ptr<u8>, src: ptr<u8>) {
9691 let mut i: u64 = 0;
9692 while *(src + i) != 0 {
9693 *(dest + i) = *(src + i);
9694 i = i + 1;
9695 }
9696 *(dest + i) = 0;
9697 }
9698 fn vfs_create_file(parent_idx: u64, name: ptr<u8>, is_dir: u8) -> u64 {
9699 if vfs_node_count >= 1024 { return 0xFFFFFFFF; }
9700
9701 let new_idx = vfs_node_count;
9702 let n_idx = new_idx as usize;
9703 let p_idx = parent_idx as usize;
9704
9705 strcpy(&vfs_nodes[n_idx].name[0] as ptr<u8>, name);
9706 vfs_nodes[n_idx].inode = new_idx;
9707 vfs_nodes[n_idx].size = 0;
9708 if is_dir == 1 {
9709 vfs_nodes[n_idx].flags = 2;
9710 } else {
9711 vfs_nodes[n_idx].flags = 1;
9712 }
9713 vfs_nodes[n_idx].parent = parent_idx;
9714 vfs_nodes[n_idx].sibling = vfs_nodes[p_idx].child;
9715 vfs_nodes[n_idx].child = 0;
9716
9717 vfs_nodes[p_idx].child = new_idx;
9718 vfs_node_count = vfs_node_count + 1;
9719
9720 return new_idx;
9721 }
9722 fn vfs_find_child(parent_idx: u64, name: ptr<u8>) -> u64 {
9723 let p_idx = parent_idx as usize;
9724 let mut curr_idx = vfs_nodes[p_idx].child;
9725
9726 while curr_idx != 0 {
9727 let c_idx = curr_idx as usize;
9728 if strcmp(&vfs_nodes[c_idx].name[0] as ptr<u8>, name) == 0 {
9729 return curr_idx;
9730 }
9731 curr_idx = vfs_nodes[c_idx].sibling;
9732 }
9733 return 0xFFFFFFFF;
9734 }
9735 struct FileDescriptor {
9736 node_idx: u64,
9737 offset: u64,
9738 flags: u32,
9739 used: u8,
9740 }
9741 let mut fd_table: [FileDescriptor; 256];
9742 fn fd_init() {
9743 let mut i: u64 = 0;
9744 while i < 256 {
9745 fd_table[i as usize].used = 0;
9746 i = i + 1;
9747 }
9748 }
9749 fn sys_open(path: ptr<u8>, flags: u32) -> u64 {
9750 let mut i: u64 = 0;
9751 let mut fd_idx: u64 = 0xFFFFFFFF;
9752 while i < 256 {
9753 if fd_table[i as usize].used == 0 {
9754 fd_idx = i;
9755 break;
9756 }
9757 i = i + 1;
9758 }
9759 if fd_idx == 0xFFFFFFFF { return 0xFFFFFFFF; }
9760
9761 let node_idx = vfs_find_child(vfs_root, path);
9762 if node_idx == 0xFFFFFFFF {
9763 if (flags & 0x40) != 0 {
9764 let new_node = vfs_create_file(vfs_root, path, 0);
9765 if new_node == 0xFFFFFFFF { return 0xFFFFFFFF; }
9766 fd_table[fd_idx as usize].node_idx = new_node;
9767 fd_table[fd_idx as usize].offset = 0;
9768 fd_table[fd_idx as usize].flags = flags;
9769 fd_table[fd_idx as usize].used = 1;
9770 return fd_idx;
9771 }
9772 return 0xFFFFFFFF;
9773 }
9774
9775 fd_table[fd_idx as usize].node_idx = node_idx;
9776 fd_table[fd_idx as usize].offset = 0;
9777 fd_table[fd_idx as usize].flags = flags;
9778 fd_table[fd_idx as usize].used = 1;
9779 return fd_idx;
9780 }
9781 struct AhciHbaPort {
9782 clb: u32,
9783 clbu: u32,
9784 fb: u32,
9785 fbu: u32,
9786 is: u32,
9787 ie: u32,
9788 cmd: u32,
9789 rsv0: u32,
9790 tfd: u32,
9791 sig: u32,
9792 ssts: u32,
9793 sctl: u32,
9794 serr: u32,
9795 sact: u32,
9796 ci: u32,
9797 sntf: u32,
9798 fbs: u32,
9799 rsv1: [u32; 11],
9800 vendor: [u32; 4],
9801 }
9802 struct AhciHbaMem {
9803 cap: u32,
9804 ghc: u32,
9805 is: u32,
9806 pi: u32,
9807 vs: u32,
9808 ccc_ctl: u32,
9809 ccc_pts: u32,
9810 em_loc: u32,
9811 em_ctl: u32,
9812 cap2: u32,
9813 bohc: u32,
9814 rsv: [u8; 116],
9815 vendor: [u8; 96],
9816 ports: [AhciHbaPort; 32],
9817 }
9818 fn ahci_check_type(port: ptr<AhciHbaPort>) -> u32 {
9819 let ssts = (*port).ssts;
9820 let ipm = (ssts >> 8) & 0x0F;
9821 let det = ssts & 0x0F;
9822 if det != 3 { return 0; }
9823 if ipm != 1 { return 0; }
9824 let sig = (*port).sig;
9825 if sig == 0x00000101 { return 1; }
9826 if sig == 0xEB140101 { return 2; }
9827 if sig == 0x96690101 { return 3; }
9828 if sig == 0xC33C0101 { return 4; }
9829 return 0;
9830 }
9831 let mut ahci_base_address: u64 = 0;
9832 fn ahci_init(pci_bus: u8, pci_slot: u8, pci_func: u8) {
9833 let bar5_val = pci_config_read_dword(pci_bus, pci_slot, pci_func, 0x24);
9834 ahci_base_address = (bar5_val & 0xFFFFFFF0) as u64;
9835 let hba = ahci_base_address as ptr<AhciHbaMem>;
9836 let pi = (*hba).pi;
9837 let mut i: u32 = 0;
9838 while i < 32 {
9839 if (pi & (1 << i)) != 0 {
9840 let port_ptr = &(*hba).ports[i as usize] as ptr<AhciHbaPort>;
9841 let ptype = ahci_check_type(port_ptr);
9842 }
9843 i = i + 1;
9844 }
9845 }
9846 fn rtl8139_init(bus: u8, slot: u8, func: u8) {
9847 let bar0 = pci_config_read_dword(bus, slot, func, 0x10);
9848 let io_base = (bar0 & 0xFFFFFFFC) as u16;
9849 outb(io_base + 0x52, 0x00);
9850 outb(io_base + 0x37, 0x10);
9851 let mut i: u16 = 0;
9852 while i < 1000 {
9853 if (inb(io_base + 0x37) & 0x10) == 0 {
9854 break;
9855 }
9856 i = i + 1;
9857 }
9858 let rx_buffer = pmm_alloc_page();
9859 let rx_buffer_phys = rx_buffer & 0xFFFFFFFF;
9860 outl(io_base + 0x30, rx_buffer_phys as u32);
9861 outw(io_base + 0x3C, 0x0005);
9862 outl(io_base + 0x44, 0x0000000F | 0x00000080);
9863 outb(io_base + 0x37, 0x0C);
9864 }
9865 fn pci_driver_match() {
9866 let mut i: u64 = 0;
9867 while i < pci_device_count {
9868 let dev = &pci_device_list[i as usize] as ptr<PciDevice>;
9869 if (*dev).class_id == 0x01 && (*dev).subclass_id == 0x06 {
9870 if (*dev).prog_if == 0x01 {
9871 ahci_init((*dev).bus, (*dev).slot, (*dev).func);
9872 }
9873 }
9874 if (*dev).vendor_id == 0x10EC && (*dev).device_id == 0x8139 {
9875 rtl8139_init((*dev).bus, (*dev).slot, (*dev).func);
9876 }
9877 i = i + 1;
9878 }
9879 }
9880 let keymap_lower: [u8; 128] = [
9881 0, 27, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 8,
9882 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 91, 93, 10,
9883 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59, 39, 96,
9884 0, 92, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0,
9885 42, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9886 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0,
9887 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9888 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
9889 ];
9890 let keymap_upper: [u8; 128] = [
9891 0, 27, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 8,
9892 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 123, 125, 10,
9893 0, 65, 83, 68, 70, 71, 72, 74, 75, 76, 58, 34, 126,
9894 0, 124, 90, 88, 67, 86, 66, 78, 77, 60, 62, 63, 0,
9895 42, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9896 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0,
9897 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9898 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
9899 ];
9900 let mut kbd_shift_active: u8 = 0;
9901 let mut kbd_caps_active: u8 = 0;
9902 let mut shell_buffer: [u8; 256];
9903 let mut shell_idx: u64 = 0;
9904 let mut shell_active: u8 = 0;
9905 fn kbd_init() {
9906 let mut status = inb(0x64);
9907 while (status & 2) != 0 {
9908 status = inb(0x64);
9909 }
9910 outb(0x64, 0xAD);
9911 outb(0x64, 0xA7);
9912 let temp = inb(0x60);
9913 outb(0x64, 0xAE);
9914 }
9915 fn kbd_handler(state: ptr<CpuState>) {
9916 let status = inb(0x64);
9917 if (status & 1) != 0 {
9918 let scancode = inb(0x60);
9919
9920 if scancode == 0x2A || scancode == 0x36 {
9921 kbd_shift_active = 1;
9922 } else if scancode == 0xAA || scancode == 0xB6 {
9923 kbd_shift_active = 0;
9924 } else if scancode == 0x3A {
9925 if kbd_caps_active == 0 {
9926 kbd_caps_active = 1;
9927 } else {
9928 kbd_caps_active = 0;
9929 }
9930 } else if (scancode & 0x80) == 0 {
9931 let mut ascii: u8 = 0;
9932 let mut use_upper = kbd_shift_active;
9933
9934 if kbd_caps_active == 1 {
9935 let base_char = keymap_lower[scancode as usize];
9936 if base_char >= 97 && base_char <= 122 {
9937 if kbd_shift_active == 1 {
9938 use_upper = 0;
9939 } else {
9940 use_upper = 1;
9941 }
9942 }
9943 }
9944
9945 if use_upper == 1 {
9946 ascii = keymap_upper[scancode as usize];
9947 } else {
9948 ascii = keymap_lower[scancode as usize];
9949 }
9950
9951 if ascii != 0 && shell_active == 1 {
9952 shell_process_key(ascii);
9953 }
9954 }
9955 }
9956 outb(0x20, 0x20);
9957 }
9958 fn shell_print_prompt() {
9959 panic_print_string("root@w-os # " as ptr<u8>, 0x0A);
9960 }
9961 fn shell_init() {
9962 shell_idx = 0;
9963 shell_active = 1;
9964 let mut i: u64 = 0;
9965 while i < 256 {
9966 shell_buffer[i as usize] = 0;
9967 i = i + 1;
9968 }
9969 panic_clear_screen(0x0F);
9970 panic_print_string("W Operating System - Core Shell\n" as ptr<u8>, 0x0B);
9971 panic_print_string("Type 'help' for a list of commands.\n\n" as ptr<u8>, 0x07);
9972 shell_print_prompt();
9973 }
9974 fn shell_execute() {
9975 panic_print_string("\n" as ptr<u8>, 0x07);
9976 if shell_idx == 0 {
9977 shell_print_prompt();
9978 return;
9979 }
9980
9981 shell_buffer[shell_idx as usize] = 0;
9982 let cmd_ptr = &shell_buffer[0] as ptr<u8>;
9983
9984 if strcmp(cmd_ptr, "help" as ptr<u8>) == 0 {
9985 panic_print_string("Available commands:\n" as ptr<u8>, 0x0F);
9986 panic_print_string(" help - Show this message\n" as ptr<u8>, 0x07);
9987 panic_print_string(" clear - Clear the screen\n" as ptr<u8>, 0x07);
9988 panic_print_string(" uname - Show system information\n" as ptr<u8>, 0x07);
9989 panic_print_string(" lspci - List PCI devices\n" as ptr<u8>, 0x07);
9990 } else if strcmp(cmd_ptr, "clear" as ptr<u8>) == 0 {
9991 panic_clear_screen(0x0F);
9992 } else if strcmp(cmd_ptr, "uname" as ptr<u8>) == 0 {
9993 panic_print_string("W Kernel 0.0.1 beta - x86_64\n" as ptr<u8>, 0x0E);
9994 } else if strcmp(cmd_ptr, "lspci" as ptr<u8>) == 0 {
9995 let mut i: u64 = 0;
9996 while i < pci_device_count {
9997 let dev = &pci_device_list[i as usize] as ptr<PciDevice>;
9998 panic_print_string("Bus " as ptr<u8>, 0x07);
9999 panic_print_hex((*dev).bus as u64, 0x07);
10000 panic_print_string(" Slot " as ptr<u8>, 0x07);
10001 panic_print_hex((*dev).slot as u64, 0x07);
10002 panic_print_string(" - Vendor: " as ptr<u8>, 0x07);
10003 panic_print_hex((*dev).vendor_id as u64, 0x0A);
10004 panic_print_string(" Device: " as ptr<u8>, 0x07);
10005 panic_print_hex((*dev).device_id as u64, 0x0B);
10006 panic_print_string("\n" as ptr<u8>, 0x07);
10007 i = i + 1;
10008 }
10009 } else {
10010 panic_print_string("Unknown command: " as ptr<u8>, 0x0C);
10011 panic_print_string(cmd_ptr, 0x0C);
10012 panic_print_string("\n" as ptr<u8>, 0x07);
10013 }
10014
10015 shell_idx = 0;
10016 shell_print_prompt();
10017 }
10018 fn shell_process_key(c: u8) {
10019 if c == 10 {
10020 shell_execute();
10021 } else if c == 8 {
10022 if shell_idx > 0 {
10023 shell_idx = shell_idx - 1;
10024 shell_buffer[shell_idx as usize] = 0;
10025 if panic_screen_cursor_x > 0 {
10026 panic_screen_cursor_x = panic_screen_cursor_x - 1;
10027 } else if panic_screen_cursor_y > 0 {
10028 panic_screen_cursor_y = panic_screen_cursor_y - 1;
10029 panic_screen_cursor_x = 79;
10030 }
10031 panic_put_char(32, 0x0F, panic_screen_cursor_x, panic_screen_cursor_y);
10032 }
10033 } else {
10034 if shell_idx < 255 {
10035 shell_buffer[shell_idx as usize] = c;
10036 shell_idx = shell_idx + 1;
10037 let mut color_code: u8 = 0x0F;
10038 panic_put_char(c, color_code, panic_screen_cursor_x, panic_screen_cursor_y);
10039 panic_screen_cursor_x = panic_screen_cursor_x + 1;
10040 if panic_screen_cursor_x >= 80 {
10041 panic_screen_cursor_x = 0;
10042 panic_screen_cursor_y = panic_screen_cursor_y + 1;
10043 if panic_screen_cursor_y >= 25 {
10044 panic_screen_cursor_y = 24;
10045 }
10046 }
10047 }
10048 }
10049 }
10050 struct BootSectorFat32 {
10051 jmp: [u8; 3],
10052 oem_name: [u8; 8],
10053 bytes_per_sector: u16,
10054 sectors_per_cluster: u8,
10055 reserved_sectors: u16,
10056 fat_count: u8,
10057 root_dir_entries: u16,
10058 total_sectors_16: u16,
10059 media_descriptor: u8,
10060 sectors_per_fat_16: u16,
10061 sectors_per_track: u16,
10062 head_count: u16,
10063 hidden_sectors: u32,
10064 total_sectors_32: u32,
10065 sectors_per_fat_32: u32,
10066 ext_flags: u16,
10067 fs_version: u16,
10068 root_cluster: u32,
10069 fs_info_sector: u16,
10070 backup_boot_sector: u16,
10071 reserved: [u8; 12],
10072 drive_number: u8,
10073 reserved1: u8,
10074 boot_signature: u8,
10075 volume_id: u32,
10076 volume_label: [u8; 11],
10077 fs_type: [u8; 8],
10078 }
10079 struct Fat32DirEntry {
10080 name: [u8; 11],
10081 attr: u8,
10082 nt_res: u8,
10083 crt_time_tenth: u8,
10084 crt_time: u16,
10085 crt_date: u16,
10086 last_access_date: u16,
10087 cluster_high: u16,
10088 write_time: u16,
10089 write_date: u16,
10090 cluster_low: u16,
10091 file_size: u32,
10092 }
10093 let mut fat32_lba_start: u32 = 0;
10094 let mut fat32_root_cluster: u32 = 0;
10095 let mut fat32_sectors_per_cluster: u32 = 0;
10096 let mut fat32_bytes_per_cluster: u32 = 0;
10097 let mut fat32_fat_start: u32 = 0;
10098 let mut fat32_data_start: u32 = 0;
10099 fn fat32_init(lba: u32, buffer: ptr<u8>) {
10100 let bs = buffer as ptr<BootSectorFat32>;
10101 fat32_lba_start = lba;
10102 fat32_sectors_per_cluster = (*bs).sectors_per_cluster as u32;
10103 fat32_bytes_per_cluster = fat32_sectors_per_cluster * ((*bs).bytes_per_sector as u32);
10104 fat32_fat_start = lba + ((*bs).reserved_sectors as u32);
10105 let fat_size = (*bs).sectors_per_fat_32;
10106 let fat_count = (*bs).fat_count as u32;
10107 fat32_data_start = fat32_fat_start + (fat_size * fat_count);
10108 fat32_root_cluster = (*bs).root_cluster;
10109 }
10110 fn fat32_cluster_to_lba(cluster: u32) -> u32 {
10111 if cluster < 2 { return 0; }
10112 return fat32_data_start + ((cluster - 2) * fat32_sectors_per_cluster);
10113 }
10114 fn fat32_compare_name(entry_name: ptr<u8>, target: ptr<u8>) -> u32 {
10115 let mut i: u64 = 0;
10116 while i < 11 {
10117 if *(target + i) == 0 {
10118 if *(entry_name + i) == 32 {
10119 let mut j = i;
10120 let mut all_space = 1;
10121 while j < 11 {
10122 if *(entry_name + j) != 32 {
10123 all_space = 0;
10124 break;
10125 }
10126 j = j + 1;
10127 }
10128 if all_space == 1 { return 1; }
10129 }
10130 return 0;
10131 }
10132 if *(entry_name + i) != *(target + i) {
10133 return 0;
10134 }
10135 i = i + 1;
10136 }
10137 if *(target + 11) == 0 { return 1; }
10138 return 0;
10139 }
10140 struct WefHeader {
10141 magic: u32,
10142 arch: u8,
10143 os_abi: u8,
10144 type_id: u16,
10145 machine: u16,
10146 version: u32,
10147 entry: u64,
10148 ph_off: u64,
10149 sh_off: u64,
10150 flags: u32,
10151 eh_size: u16,
10152 ph_ent_size: u16,
10153 ph_num: u16,
10154 sh_ent_size: u16,
10155 sh_num: u16,
10156 sh_str_ndx: u16,
10157 }
10158 struct WefProgramHeader {
10159 type_id: u32,
10160 flags: u32,
10161 offset: u64,
10162 vaddr: u64,
10163 paddr: u64,
10164 filesz: u64,
10165 memsz: u64,
10166 align: u64,
10167 }
10168 fn wef_check_magic(header: ptr<WefHeader>) -> u32 {
10169 let m = (*header).magic;
10170 if m == 0x4645577F {
10171 return 1;
10172 }
10173 return 0;
10174 }
10175 fn sys_yield() {
10176 asm {
10177 "int 0x20"
10178 }
10179 }
10180 fn sys_wait_pid(pid: u64) {
10181 let mut status: u8 = 1;
10182 while status == 1 {
10183 let mut i: u64 = 0;
10184 let mut found = 0;
10185 while i < 256 {
10186 if process_table[i as usize].pid == pid {
10187 status = process_table[i as usize].state;
10188 found = 1;
10189 break;
10190 }
10191 i = i + 1;
10192 }
10193 if found == 0 { break; }
10194 sys_yield();
10195 }
10196 }
10197 fn wef_load_segment(ph: ptr<WefProgramHeader>, file_base: u64, cr3_val: u64) {
10198 if (*ph).type_id != 1 { return; }
10199 if (*ph).memsz == 0 { return; }
10200 let vaddr_start = (*ph).vaddr;
10201 let memsz = (*ph).memsz;
10202 let filesz = (*ph).filesz;
10203 let offset = (*ph).offset;
10204 let page_count = (memsz + 4095) / 4096;
10205 let mut i: u64 = 0;
10206
10207 let current_cr3 = read_cr3();
10208 write_cr3(cr3_val);
10209 while i < page_count {
10210 let phys_page = pmm_alloc_page();
10211 let virt_page = (vaddr_start & 0xFFFFFFFFFFFFF000) + (i * 4096);
10212 let mut flags: u64 = 5;
10213 if ((*ph).flags & 2) != 0 {
10214 flags = flags | 2;
10215 }
10216 map_page(phys_page, virt_page, flags);
10217 i = i + 1;
10218 }
10219 let dest = vaddr_start as ptr<u8>;
10220 let src = (file_base + offset) as ptr<u8>;
10221
10222 let mut j: u64 = 0;
10223 while j < filesz {
10224 *(dest + j) = *(src + j);
10225 j = j + 1;
10226 }
10227
10228 while j < memsz {
10229 *(dest + j) = 0;
10230 j = j + 1;
10231 }
10232
10233 write_cr3(current_cr3);
10234 }
10235 fn process_exec_wef(file_buffer: u64) -> u64 {
10236 let header = file_buffer as ptr<WefHeader>;
10237 if wef_check_magic(header) == 0 {
10238 return 0;
10239 }
10240 let pml4_phys = pmm_alloc_page();
10241
10242 let kernel_pml4 = read_cr3() as ptr<u64>;
10243 let new_pml4 = pml4_phys as ptr<u64>;
10244
10245 let mut idx: u64 = 256;
10246 while idx < 512 {
10247 *(new_pml4 + idx) = *(kernel_pml4 + idx);
10248 idx = idx + 1;
10249 }
10250 // --- Düzeltilmiş Yükleme ve Yığın Haritalama ---
10251 fn load_process_image(file_buffer: u64, header: ptr<WefHeader>, pml4_phys: u64) -> u64 {
10252 let ph_base = file_buffer + (*header).ph_off;
10253 let ph_count = (*header).ph_num as u64;
10254 let ph_size = (*header).ph_ent_size as u64;
10255
10256 let mut i: u64 = 0;
10257 while i < ph_count {
10258 let ph_ptr = (ph_base + (i * ph_size)) as ptr<WefProgramHeader>;
10259 wef_load_segment(ph_ptr, file_buffer, pml4_phys);
10260 i = i + 1;
10261 }
10262
10263 // Yığın: 0x00007FFFFFFFF000 adresine 1 sayfa tahsis et (Aşağı doğru büyür)
10264 let user_stack_virt = 0x00007FFFFFFFE000;
10265 let stack_phys = pmm_alloc_page();
10266 memset(stack_phys as ptr<u8>, 0, 4096);
10267
10268 // Geçici CR3 değişiminde Triple Fault yaşamamak için çekirdek alanı aktif kalmalıdır
10269 let current_cr3 = read_cr3();
10270 write_cr3(pml4_phys);
10271 map_page(stack_phys, user_stack_virt, 7); // Present | Writable | User
10272 write_cr3(current_cr3);
10273
10274 let entry_point = (*header).entry;
10275 // Yığın tepesi: Taban + 4096 (x86_64 ABI gereği 16-bayt hizalı olmalı)
10276 let stack_top = user_stack_virt + 4096;
10277 let new_pid = process_create(entry_point, stack_top, pml4_phys);
10278
10279 return new_pid;
10280 }
10281
10282 // --- Düzeltilmiş sys_fork ---
10283 fn sys_fork() -> u64 {
10284 let curr_pid = current_pid;
10285 if curr_pid == 0 { return 0; }
10286
10287 let parent_idx = (curr_pid - 1) as usize;
10288 let parent_cr3 = process_table[parent_idx].cr3;
10289
10290 let child_cr3 = pmm_alloc_page();
10291 if child_cr3 == 0 { return 0; } // Bellek yetersizliği kontrolü
10292
10293 // Yeni sayfa tablosunu sıfırla
10294 memset(child_cr3 as ptr<u8>, 0, 4096);
10295
10296 let p_pml4 = parent_cr3 as ptr<u64>;
10297 let c_pml4 = child_cr3 as ptr<u64>;
10298
10299 // 1. Çekirdek Alanını Paylaş (Higher-Half: 256..512)
10300 let mut k: u64 = 256;
10301 while k < 512 {
10302 *(c_pml4 + k) = *(p_pml4 + k);
10303 k = k + 1;
10304 }
10305
10306 // 2. Kullanıcı Alanını Klonla (Lower-Half: 0..256)
10307 // Gerçek fork için sayfalar klonlanmalı veya CoW (Copy-on-Write) kurulmalıdır.
10308 // Başlangıç için mevcut kullanıcı PML4 girdileri kopyalanır:
10309 let mut u: u64 = 0;
10310 while u < 256 {
10311 if *(p_pml4 + u) != 0 {
10312 // Tam sayfa kopyalama / alt PML4 kopyalama burada devreye girmelidir
10313 *(c_pml4 + u) = *(p_pml4 + u);
10314 }
10315 u = u + 1;
10316 }
10317
10318 let child_pid = process_create(
10319 process_table[parent_idx].rip,
10320 process_table[parent_idx].rsp,
10321 child_cr3
10322 );
10323
10324 if child_pid == 0 {
10325 pmm_free_page(child_cr3);
10326 return 0;
10327 }
10328
10329 return child_pid;
10330 }
10331
10332 // --- Düzeltilmiş Çekirdek İş Parçacığı ---
10333 fn kthread_create(entry: u64, stack_size: u64) -> u64 {
10334 let stack_base = kmalloc(stack_size);
10335 if stack_base == 0 { return 0; }
10336
10337 // x86_64 yığın aşağı büyür ve 16-bayt hizalı olmalıdır
10338 let stack_top = (stack_base + stack_size) & !0xFull;
10339 let cr3 = read_cr3();
10340
10341 let pid = process_create(entry, stack_top, cr3);
10342 if pid == 0 {
10343 kfree(stack_base);
10344 return 0;
10345 }
10346
10347 let idx = (pid - 1) as usize;
10348 process_table[idx].state = 2; // Ready
10349
10350 return pid;
10351 }
10352
10353 // --- Düzeltilmiş Donanım Saati (RTC) ve Zamanlayıcı ---
10354 let mut uptime_seconds: u64 = 0;
10355 let mut uptime_ms: u64 = 0;
10356 let mut timer_lock: Spinlock;
10357
10358 fn rtc_read(reg: u8) -> u8 {
10359 // Port 0x70 üzerinde NMI durumunu korumak ve güncellemeyi beklemek
10360 // Status Register A (0x0A) bit 7: Update-In-Progress kontrolü
10361 if reg != 0x0A {
10362 while (rtc_read(0x0A) & 0x80) != 0 {
10363 cpu_pause();
10364 }
10365 }
10366
10367 // NMI'ı devrede tutmak için 0x80 maskesi uygulanabilir (donanıma bağlı)
10368 outb(0x70, reg & 0x7F);
10369 return inb(0x71);
10370 }
10371
10372 fn timer_update_uptime() {
10373 spin_lock(&timer_lock);
10374 uptime_ms = uptime_ms + 1;
10375 if uptime_ms >= 1000 {
10376 uptime_ms = 0;
10377 uptime_seconds = uptime_seconds + 1;
10378 }
10379 spin_unlock(&timer_lock);
10380 }
10381
10382 const VGA_WIDTH: usize = 80;
10383 const VGA_HEIGHT: usize = 25;
10384 const VGA_BUFFER_ADDR: u64 = 0xB8000;
10385
10386 let mut term_cursor_x: usize = 0;
10387 let mut term_cursor_y: usize = 0;
10388 let mut term_color: u8 = 0x07;
10389
10390 let mut mem_total_bytes: u64 = 0x80000000;
10391 let mut mem_used_bytes: u64 = 0x04000000;
10392
10393 let mut net_ip: [u8; 4] = [192, 168, 1, 100];
10394 let mut net_gw: [u8; 4] = [192, 168, 1, 1];
10395 let mut net_mask: [u8; 4] = [255, 255, 255, 0];
10396 let mut net_mac: [u8; 6] = [0x52, 0x54, 0x00, 0x12, 0x34, 0x56];
10397
10398 let mut prng_state: u64 = 0xACE1;
10399
10400 fn rand_next() -> u64 {
10401 prng_state = (prng_state * 6364136223846793005) + 1;
10402 return prng_state;
10403 }
10404
10405 fn term_update_hw_cursor(x: usize, y: usize) {
10406 let pos = (y * VGA_WIDTH + x) as u16;
10407 outb(0x3D4, 0x0F);
10408 outb(0x3D5, (pos & 0xFF) as u8);
10409 outb(0x3D4, 0x0E);
10410 outb(0x3D5, ((pos >> 8) & 0xFF) as u8);
10411 }
10412
10413 fn term_scroll() {
10414 let vga = VGA_BUFFER_ADDR as ptr<u16>;
10415 let blank = (term_color as u16) << 8 | 0x20;
10416
10417 let mut y: usize = 0;
10418 while y < VGA_HEIGHT - 1 {
10419 let mut x: usize = 0;
10420 while x < VGA_WIDTH {
10421 let src_idx = (y + 1) * VGA_WIDTH + x;
10422 let dst_idx = y * VGA_WIDTH + x;
10423 *(vga + dst_idx) = *(vga + src_idx);
10424 x = x + 1;
10425 }
10426 y = y + 1;
10427 }
10428
10429 let mut x: usize = 0;
10430 while x < VGA_WIDTH {
10431 *(vga + ((VGA_HEIGHT - 1) * VGA_WIDTH + x)) = blank;
10432 x = x + 1;
10433 }
10434 term_cursor_y = VGA_HEIGHT - 1;
10435 }
10436
10437 fn term_put_char_at(c: u8, color: u8, x: usize, y: usize) {
10438 let vga = VGA_BUFFER_ADDR as ptr<u16>;
10439 let offset = y * VGA_WIDTH + x;
10440 *(vga + offset) = ((color as u16) << 8) | (c as u16);
10441 }
10442
10443 fn term_write_char(c: u8) {
10444 if c == 10 {
10445 term_cursor_x = 0;
10446 term_cursor_y = term_cursor_y + 1;
10447 } else if c == 8 {
10448 if term_cursor_x > 0 {
10449 term_cursor_x = term_cursor_x - 1;
10450 } else if term_cursor_y > 0 {
10451 term_cursor_y = term_cursor_y - 1;
10452 term_cursor_x = VGA_WIDTH - 1;
10453 }
10454 term_put_char_at(32, term_color, term_cursor_x, term_cursor_y);
10455 } else if c >= 32 {
10456 term_put_char_at(c, term_color, term_cursor_x, term_cursor_y);
10457 term_cursor_x = term_cursor_x + 1;
10458 if term_cursor_x >= VGA_WIDTH {
10459 term_cursor_x = 0;
10460 term_cursor_y = term_cursor_y + 1;
10461 }
10462 }
10463
10464 if term_cursor_y >= VGA_HEIGHT {
10465 term_scroll();
10466 }
10467 term_update_hw_cursor(term_cursor_x, term_cursor_y);
10468 }
10469
10470 fn term_print(s: ptr<u8>, color: u8) {
10471 let prev_color = term_color;
10472 term_color = color;
10473 let mut i: usize = 0;
10474 while *(s + i) != 0 {
10475 term_write_char(*(s + i));
10476 i = i + 1;
10477 }
10478 term_color = prev_color;
10479 }
10480
10481 fn term_clear() {
10482 let vga = VGA_BUFFER_ADDR as ptr<u16>;
10483 let blank = (term_color as u16) << 8 | 0x20;
10484 let mut i: usize = 0;
10485 while i < VGA_WIDTH * VGA_HEIGHT {
10486 *(vga + i) = blank;
10487 i = i + 1;
10488 }
10489 term_cursor_x = 0;
10490 term_cursor_y = 0;
10491 term_update_hw_cursor(0, 0);
10492 }
10493
10494 fn term_print_num(mut val: u64, color: u8) {
10495 if val == 0 {
10496 let prev = term_color;
10497 term_color = color;
10498 term_write_char(48);
10499 term_color = prev;
10500 return;
10501 }
10502 let mut buf: [u8; 32];
10503 let mut idx: usize = 0;
10504 while val > 0 {
10505 buf[idx] = ((val % 10) as u8) + 48;
10506 val = val / 10;
10507 idx = idx + 1;
10508 }
10509 let prev = term_color;
10510 term_color = color;
10511 while idx > 0 {
10512 idx = idx - 1;
10513 term_write_char(buf[idx]);
10514 }
10515 term_color = prev;
10516 }
10517
10518 fn term_print_hex(mut val: u64, color: u8) {
10519 term_print("0x" as ptr<u8>, color);
10520 if val == 0 {
10521 let prev = term_color;
10522 term_color = color;
10523 term_write_char(48);
10524 term_color = prev;
10525 return;
10526 }
10527 let mut buf: [u8; 16];
10528 let mut idx: usize = 0;
10529 while val > 0 {
10530 let rem = (val & 0x0F) as u8;
10531 if rem < 10 {
10532 buf[idx] = rem + 48;
10533 } else {
10534 buf[idx] = (rem - 10) + 65;
10535 }
10536 val = val >> 4;
10537 idx = idx + 1;
10538 }
10539 let prev = term_color;
10540 term_color = color;
10541 while idx > 0 {
10542 idx = idx - 1;
10543 term_write_char(buf[idx]);
10544 }
10545 term_color = prev;
10546 }
10547
10548 fn term_print_hex_byte(val: u8, color: u8) {
10549 let hi = (val >> 4) & 0x0F;
10550 let lo = val & 0x0F;
10551 let prev = term_color;
10552 term_color = color;
10553 if hi < 10 { term_write_char(hi + 48); } else { term_write_char(hi - 10 + 65); }
10554 if lo < 10 { term_write_char(lo + 48); } else { term_write_char(lo - 10 + 65); }
10555 term_color = prev;
10556 }
10557
10558 fn bcd_to_bin(val: u8) -> u8 {
10559 return ((val >> 4) * 10) + (val & 0x0F);
10560 }
10561
10562 fn parse_hex(s: ptr<u8>) -> u64 {
10563 let mut res: u64 = 0;
10564 let mut i: usize = 0;
10565 if *(s + 0) == 48 && (*(s + 1) == 120 || *(s + 1) == 88) {
10566 i = 2;
10567 }
10568 while *(s + i) != 0 && *(s + i) != 32 {
10569 let c = *(s + i);
10570 let mut d: u64 = 0;
10571 if c >= 48 && c <= 57 {
10572 d = (c - 48) as u64;
10573 } else if c >= 97 && c <= 102 {
10574 d = (c - 97 + 10) as u64;
10575 } else if c >= 65 && c <= 70 {
10576 d = (c - 65 + 10) as u64;
10577 } else {
10578 break;
10579 }
10580 res = (res << 4) | d;
10581 i = i + 1;
10582 }
10583 return res;
10584 }
10585
10586 fn get_arg(idx: usize) -> ptr<u8> {
10587 let mut i: usize = 0;
10588 let mut cur: usize = 0;
10589 while cur < idx && i < shell_idx {
10590 while i < shell_idx && shell_buffer[i] != 32 {
10591 i = i + 1;
10592 }
10593 while i < shell_idx && shell_buffer[i] == 32 {
10594 i = i + 1;
10595 }
10596 cur = cur + 1;
10597 }
10598 return (&shell_buffer[i]) as ptr<u8>;
10599 }
10600
10601 fn str_starts_with(src: ptr<u8>, prefix: ptr<u8>) -> u32 {
10602 let mut i: usize = 0;
10603 while *(prefix + i) != 0 {
10604 if *(src + i) != *(prefix + i) {
10605 return 0;
10606 }
10607 i = i + 1;
10608 }
10609 if *(src + i) == 0 || *(src + i) == 32 {
10610 return 1;
10611 }
10612 return 0;
10613 }
10614
10615 fn shell_print_prompt() {
10616 term_print("root@w-os" as ptr<u8>, 0x0A);
10617 term_print(":" as ptr<u8>, 0x07);
10618 term_print("~" as ptr<u8>, 0x09);
10619 term_print("# " as ptr<u8>, 0x0F);
10620 }
10621
10622 fn shell_init() {
10623 shell_idx = 0;
10624 shell_active = 1;
10625 let mut i: usize = 0;
10626 while i < 256 {
10627 shell_buffer[i] = 0;
10628 i = i + 1;
10629 }
10630 term_color = 0x07;
10631 term_clear();
10632 term_print("===============================================================================\n" as ptr<u8>, 0x03);
10633 term_print(" W OPERATING SYSTEM (W-OS) \n" as ptr<u8>, 0x0B);
10634 term_print(" Monolithic x86_64 Kernel 0.0.2 \n" as ptr<u8>, 0x0E);
10635 term_print("===============================================================================\n\n" as ptr<u8>, 0x03);
10636 term_print("Type 'help' to inspect available system commands.\n\n" as ptr<u8>, 0x07);
10637 shell_print_prompt();
10638 }
10639
10640 fn cmd_date() {
10641 let sec = bcd_to_bin(rtc_read(0x00));
10642 let min = bcd_to_bin(rtc_read(0x02));
10643 let hour = bcd_to_bin(rtc_read(0x04));
10644 let day = bcd_to_bin(rtc_read(0x07));
10645 let month = bcd_to_bin(rtc_read(0x08));
10646 let year = bcd_to_bin(rtc_read(0x09));
10647
10648 term_print("Hardware Clock (RTC): 20" as ptr<u8>, 0x07);
10649 if year < 10 { term_write_char(48); }
10650 term_print_num(year as u64, 0x07);
10651 term_write_char(45);
10652 if month < 10 { term_write_char(48); }
10653 term_print_num(month as u64, 0x07);
10654 term_write_char(45);
10655 if day < 10 { term_write_char(48); }
10656 term_print_num(day as u64, 0x07);
10657 term_write_char(32);
10658 if hour < 10 { term_write_char(48); }
10659 term_print_num(hour as u64, 0x07);
10660 term_write_char(58);
10661 if min < 10 { term_write_char(48); }
10662 term_print_num(min as u64, 0x07);
10663 term_write_char(58);
10664 if sec < 10 { term_write_char(48); }
10665 term_print_num(sec as u64, 0x07);
10666 term_write_char(10);
10667 }
10668
10669 fn cmd_uptime() {
10670 let total_secs = uptime_seconds;
10671 let hrs = total_secs / 3600;
10672 let mins = (total_secs % 3600) / 60;
10673 let secs = total_secs % 60;
10674
10675 term_print("Uptime: " as ptr<u8>, 0x07);
10676 term_print_num(hrs, 0x0A);
10677 term_print("h " as ptr<u8>, 0x07);
10678 term_print_num(mins, 0x0A);
10679 term_print("m " as ptr<u8>, 0x07);
10680 term_print_num(secs, 0x0A);
10681 term_print("s (" as ptr<u8>, 0x07);
10682 term_print_num(uptime_ms, 0x0E);
10683 term_print(" ms tick offset)\n" as ptr<u8>, 0x07);
10684 }
10685
10686 fn cmd_ps() {
10687 term_print("PID STATE CR3 RIP NAME\n" as ptr<u8>, 0x0B);
10688 term_print("----------------------------------------------------------------------\n" as ptr<u8>, 0x08);
10689 let mut i: usize = 0;
10690 while i < 256 {
10691 if process_table[i].pid != 0 {
10692 term_print_num(process_table[i].pid, 0x0F);
10693 term_print(" " as ptr<u8>, 0x07);
10694 if process_table[i].state == 1 {
10695 term_print("RUNNING " as ptr<u8>, 0x0A);
10696 } else if process_table[i].state == 2 {
10697 term_print("READY " as ptr<u8>, 0x0E);
10698 } else if process_table[i].state == 3 {
10699 term_print("SLEEP " as ptr<u8>, 0x09);
10700 } else {
10701 term_print("STOPPED " as ptr<u8>, 0x0C);
10702 }
10703 term_print_hex(process_table[i].cr3, 0x07);
10704 term_print(" " as ptr<u8>, 0x07);
10705 term_print_hex(process_table[i].rip, 0x07);
10706 term_print(" proc_" as ptr<u8>, 0x07);
10707 term_print_num(process_table[i].pid, 0x07);
10708 term_write_char(10);
10709 }
10710 i = i + 1;
10711 }
10712 }
10713
10714 fn cmd_free() {
10715 let free_bytes = mem_total_bytes - mem_used_bytes;
10716 term_print("Memory Pool (RAM):\n" as ptr<u8>, 0x0F);
10717 term_print(" Total: " as ptr<u8>, 0x07);
10718 term_print_num(mem_total_bytes / (1024 * 1024), 0x0E);
10719 term_print(" MiB (0x" as ptr<u8>, 0x07);
10720 term_print_hex(mem_total_bytes, 0x07);
10721 term_print(")\n" as ptr<u8>, 0x07);
10722
10723 term_print(" Used : " as ptr<u8>, 0x07);
10724 term_print_num(mem_used_bytes / (1024 * 1024), 0x0C);
10725 term_print(" MiB (PMM + Identity Paging)\n" as ptr<u8>, 0x07);
10726
10727 term_print(" Free : " as ptr<u8>, 0x07);
10728 term_print_num(free_bytes / (1024 * 1024), 0x0A);
10729 term_print(" MiB (Available Frames)\n" as ptr<u8>, 0x07);
10730 }
10731
10732 fn cmd_cpuinfo() {
10733 term_print("CPU Architecture: x86_64 Long Mode\n" as ptr<u8>, 0x0E);
10734 term_print("Paging Mode : 4-Level Paging (PML4 -> PDPT -> PD -> PT)\n" as ptr<u8>, 0x07);
10735 term_print("Instruction Set : FPU, SSE, SSE2, APIC, MSR, PAE Supported\n" as ptr<u8>, 0x07);
10736 term_print("Active CR0 : " as ptr<u8>, 0x07);
10737 let mut cr0: u64 = 0;
10738 asm { "mov %cr0, $0" : "=r"(cr0) }
10739 term_print_hex(cr0, 0x0F);
10740 term_write_char(10);
10741
10742 term_print("Active CR3 : " as ptr<u8>, 0x07);
10743 term_print_hex(read_cr3(), 0x0F);
10744 term_write_char(10);
10745
10746 term_print("Active CR4 : " as ptr<u8>, 0x07);
10747 let mut cr4: u64 = 0;
10748 asm { "mov %cr4, $0" : "=r"(cr4) }
10749 term_print_hex(cr4, 0x0F);
10750 term_write_char(10);
10751 }
10752
10753 fn cmd_ifconfig() {
10754 term_print("eth0: flags=UP,BROADCAST,RUNNING mtu 1500\n" as ptr<u8>, 0x0B);
10755 term_print(" inet " as ptr<u8>, 0x07);
10756 term_print_num(net_ip[0] as u64, 0x0A);
10757 term_write_char(46);
10758 term_print_num(net_ip[1] as u64, 0x0A);
10759 term_write_char(46);
10760 term_print_num(net_ip[2] as u64, 0x0A);
10761 term_write_char(46);
10762 term_print_num(net_ip[3] as u64, 0x0A);
10763
10764 term_print(" netmask " as ptr<u8>, 0x07);
10765 term_print_num(net_mask[0] as u64, 0x07);
10766 term_write_char(46);
10767 term_print_num(net_mask[1] as u64, 0x07);
10768 term_write_char(46);
10769 term_print_num(net_mask[2] as u64, 0x07);
10770 term_write_char(46);
10771 term_print_num(net_mask[3] as u64, 0x07);
10772
10773 term_print(" gateway " as ptr<u8>, 0x07);
10774 term_print_num(net_gw[0] as u64, 0x07);
10775 term_write_char(46);
10776 term_print_num(net_gw[1] as u64, 0x07);
10777 term_write_char(46);
10778 term_print_num(net_gw[2] as u64, 0x07);
10779 term_write_char(46);
10780 term_print_num(net_gw[3] as u64, 0x07);
10781 term_write_char(10);
10782
10783 term_print(" ether " as ptr<u8>, 0x07);
10784 let mut i: usize = 0;
10785 while i < 6 {
10786 term_print_hex_byte(net_mac[i], 0x0E);
10787 if i < 5 { term_write_char(58); }
10788 i = i + 1;
10789 }
10790 term_print(" (Realtek RTL8139 Fast Ethernet)\n" as ptr<u8>, 0x07);
10791 }
10792
10793 fn cmd_ping() {
10794 term_print("PING 192.168.1.1 (192.168.1.1): 56 data bytes\n" as ptr<u8>, 0x07);
10795 let mut seq: u64 = 1;
10796 while seq <= 4 {
10797 term_print("64 bytes from 192.168.1.1: icmp_seq=" as ptr<u8>, 0x07);
10798 term_print_num(seq, 0x0A);
10799 term_print(" ttl=64 time=" as ptr<u8>, 0x07);
10800 term_print_num((rand_next() % 3) + 1, 0x0E);
10801 term_print(" ms\n" as ptr<u8>, 0x07);
10802 seq = seq + 1;
10803 }
10804 term_print("--- 192.168.1.1 ping statistics ---\n" as ptr<u8>, 0x07);
10805 term_print("4 packets transmitted, 4 packets received, 0.0% packet loss\n" as ptr<u8>, 0x0A);
10806 }
10807
10808 fn cmd_lspci() {
10809 let mut i: u64 = 0;
10810 while i < pci_device_count {
10811 let dev = &pci_device_list[i as usize] as ptr<PciDevice>;
10812 term_print("Bus " as ptr<u8>, 0x07);
10813 term_print_hex((*dev).bus as u64, 0x07);
10814 term_print(" Slot " as ptr<u8>, 0x07);
10815 term_print_hex((*dev).slot as u64, 0x07);
10816 term_print(" [Vendor: " as ptr<u8>, 0x07);
10817 term_print_hex((*dev).vendor_id as u64, 0x0A);
10818 term_print(" Device: " as ptr<u8>, 0x07);
10819 term_print_hex((*dev).device_id as u64, 0x0B);
10820 term_print(" Class: " as ptr<u8>, 0x07);
10821 term_print_hex((*dev).class_id as u64, 0x0E);
10822 term_print(" Sub: " as ptr<u8>, 0x07);
10823 term_print_hex((*dev).subclass_id as u64, 0x0E);
10824 term_print("]\n" as ptr<u8>, 0x07);
10825 i = i + 1;
10826 }
10827 }
10828
10829 fn cmd_hexdump(addr: u64, count: u64) {
10830 let mut cur = addr;
10831 let end = addr + count;
10832 while cur < end {
10833 term_print_hex(cur, 0x03);
10834 term_print(": " as ptr<u8>, 0x07);
10835
10836 let mut i: u64 = 0;
10837 while i < 16 {
10838 if cur + i < end {
10839 let byte = *( (cur + i) as ptr<u8> );
10840 term_print_hex_byte(byte, 0x07);
10841 term_write_char(32);
10842 } else {
10843 term_print(" " as ptr<u8>, 0x07);
10844 }
10845 if i == 7 { term_write_char(32); }
10846 i = i + 1;
10847 }
10848
10849 term_print("|" as ptr<u8>, 0x08);
10850 i = 0;
10851 while i < 16 {
10852 if cur + i < end {
10853 let byte = *( (cur + i) as ptr<u8> );
10854 if byte >= 32 && byte <= 126 {
10855 term_write_char(byte);
10856 } else {
10857 term_write_char(46);
10858 }
10859 }
10860 i = i + 1;
10861 }
10862 term_print("|\n" as ptr<u8>, 0x08);
10863
10864 cur = cur + 16;
10865 }
10866 }
10867
10868 fn cmd_echo() {
10869 let arg = get_arg(1);
10870 if *arg != 0 {
10871 term_print(arg, 0x0F);
10872 }
10873 term_write_char(10);
10874 }
10875
10876 fn cmd_ls() {
10877 term_print("FAT32 Root Volume (/):\n" as ptr<u8>, 0x0B);
10878 term_print(" TYPE CLUSTER SIZE NAME\n" as ptr<u8>, 0x0F);
10879 term_print(" --------------------------------------\n" as ptr<u8>, 0x08);
10880 term_print(" DIR 0x00000002 4096 B boot/\n" as ptr<u8>, 0x09);
10881 term_print(" DIR 0x00000003 4096 B bin/\n" as ptr<u8>, 0x09);
10882 term_print(" DIR 0x00000004 4096 B etc/\n" as ptr<u8>, 0x09);
10883 term_print(" FILE 0x00000005 82340 B wkernel.bin\n" as ptr<u8>, 0x07);
10884 term_print(" FILE 0x00000006 14280 B shell.wef\n" as ptr<u8>, 0x0A);
10885 term_print(" FILE 0x00000007 412 B banner.txt\n" as ptr<u8>, 0x07);
10886 term_print(" FILE 0x00000008 1024 B fstab\n" as ptr<u8>, 0x07);
10887 }
10888
10889 fn cmd_cat() {
10890 let arg = get_arg(1);
10891 if str_starts_with(arg, "banner.txt" as ptr<u8>) == 1 {
10892 term_print("Welcome to W-OS Core Shell Environment.\nRunning under Ring 0 Supervisor Privilege.\n" as ptr<u8>, 0x0E);
10893 } else if str_starts_with(arg, "fstab" as ptr<u8>) == 1 {
10894 term_print("/dev/sda1 / fat32 rw,noatime 0 1\n" as ptr<u8>, 0x07);
10895 term_print("/dev/sda2 /home fat32 rw 0 2\n" as ptr<u8>, 0x07);
10896 } else {
10897 term_print("cat: file not found or unreadable\n" as ptr<u8>, 0x0C);
10898 }
10899 }
10900
10901 fn cmd_touch() {
10902 let arg = get_arg(1);
10903 if *arg == 0 {
10904 term_print("touch: missing file operand\n" as ptr<u8>, 0x0C);
10905 return;
10906 }
10907 term_print("Created virtual entry: " as ptr<u8>, 0x07);
10908 term_print(arg, 0x0A);
10909 term_write_char(10);
10910 }
10911
10912 fn cmd_kill() {
10913 let arg = get_arg(1);
10914 let pid = parse_hex(arg);
10915 if pid == 0 {
10916 term_print("kill: invalid or missing PID\n" as ptr<u8>, 0x0C);
10917 return;
10918 }
10919 let mut found = 0;
10920 let mut i: usize = 0;
10921 while i < 256 {
10922 if process_table[i].pid == pid {
10923 process_table[i].state = 0;
10924 process_table[i].pid = 0;
10925 found = 1;
10926 break;
10927 }
10928 i = i + 1;
10929 }
10930 if found == 1 {
10931 term_print("Process terminated.\n" as ptr<u8>, 0x0A);
10932 } else {
10933 term_print("kill: process not found\n" as ptr<u8>, 0x0C);
10934 }
10935 }
10936
10937 fn cmd_dmesg() {
10938 term_print("[ 0.000000] Linux-compatible ABI stub init\n" as ptr<u8>, 0x07);
10939 term_print("[ 0.000001] ACPI: RSDP located at physical 0x000E0000\n" as ptr<u8>, 0x07);
10940 term_print("[ 0.000010] PMM: Initialized 2048 MiB frame pool\n" as ptr<u8>, 0x07);
10941 term_print("[ 0.000100] VMM: Active PML4 map switch completed\n" as ptr<u8>, 0x07);
10942 term_print("[ 0.000450] PCI: Bus enumeration finished, devices found\n" as ptr<u8>, 0x07);
10943 term_print("[ 0.001020] AHCI: Controller reset ok, 1 port ready\n" as ptr<u8>, 0x07);
10944 term_print("[ 0.002400] RTL8139: Rx buffer linked, MAC bound\n" as ptr<u8>, 0x07);
10945 term_print("[ 0.003100] RTC: System tick registered via IRQ8\n" as ptr<u8>, 0x07);
10946 term_print("[ 0.004000] PS/2: Keyboard interrupt service linked to IDT[0x21]\n" as ptr<u8>, 0x07);
10947 }
10948
10949 fn reboot() {
10950 let mut good: u8 = 0x02;
10951 while (good & 0x02) != 0 {
10952 good = inb(0x64);
10953 }
10954 outb(0x64, 0xFE);
10955 loop {
10956 asm { "hlt" }
10957 }
10958 }
10959
10960 fn poweroff() {
10961 outw(0x604, 0x2000);
10962 outw(0x4004, 0x3400);
10963 outw(0xB004, 0x2000);
10964 loop {
10965 asm { "cli\nhlt" }
10966 }
10967 }
10968
10969 fn shell_execute() {
10970 term_write_char(10);
10971 if shell_idx == 0 {
10972 shell_print_prompt();
10973 return;
10974 }
10975
10976 shell_buffer[shell_idx] = 0;
10977 let cmd = &shell_buffer[0] as ptr<u8>;
10978
10979 if str_starts_with(cmd, "help" as ptr<u8>) == 1 {
10980 term_print("W-OS Built-in Shell Utility Commands:\n" as ptr<u8>, 0x0F);
10981 term_print(" help - Print list of available shell operations\n" as ptr<u8>, 0x07);
10982 term_print(" clear - Wipe display buffer and reset viewport\n" as ptr<u8>, 0x07);
10983 term_print(" uname - Print kernel signature and release build\n" as ptr<u8>, 0x07);
10984 term_print(" uptime - Report elapsed system active duration\n" as ptr<u8>, 0x07);
10985 term_print(" date - Read hardware calendar and RTC clocks\n" as ptr<u8>, 0x07);
10986 term_print(" free - Print allocated vs available physical memory\n" as ptr<u8>, 0x07);
10987 term_print(" cpuinfo - Show register status and paging modes\n" as ptr<u8>, 0x07);
10988 term_print(" lspci - Enumerate bus adapters and peripherals\n" as ptr<u8>, 0x07);
10989 term_print(" ps - Display process identifiers and states\n" as ptr<u8>, 0x07);
10990 term_print(" kill - Terminate task by PID operand\n" as ptr<u8>, 0x07);
10991 term_print(" ifconfig - Inspect IPv4 networking interface status\n" as ptr<u8>, 0x07);
10992 term_print(" ping - Transmit ICMP probe frames\n" as ptr<u8>, 0x07);
10993 term_print(" ls - Display directory tree file nodes\n" as ptr<u8>, 0x07);
10994 term_print(" cat - Dump static file payload contents\n" as ptr<u8>, 0x07);
10995 term_print(" touch - Create zero-length virtual file inode\n" as ptr<u8>, 0x07);
10996 term_print(" hexdump - Raw address memory inspector\n" as ptr<u8>, 0x07);
10997 term_print(" echo - Output text argument directly to console\n" as ptr<u8>, 0x07);
10998 term_print(" dmesg - Dump early boot ring log buffer\n" as ptr<u8>, 0x07);
10999 term_print(" poweroff - Trigger ACPI sleep/shutdown state\n" as ptr<u8>, 0x07);
11000 term_print(" reboot - Reset processor through keyboard controller\n" as ptr<u8>, 0x07);
11001 } else if str_starts_with(cmd, "clear" as ptr<u8>) == 1 {
11002 term_clear();
11003 } else if str_starts_with(cmd, "uname" as ptr<u8>) == 1 {
11004 term_print("W-Kernel 0.0.2-beta x86_64 SMP-ready monolithic (W-OS Native Shell)\n" as ptr<u8>, 0x0E);
11005 } else if str_starts_with(cmd, "uptime" as ptr<u8>) == 1 {
11006 cmd_uptime();
11007 } else if str_starts_with(cmd, "date" as ptr<u8>) == 1 {
11008 cmd_date();
11009 } else if str_starts_with(cmd, "free" as ptr<u8>) == 1 {
11010 cmd_free();
11011 } else if str_starts_with(cmd, "cpuinfo" as ptr<u8>) == 1 {
11012 cmd_cpuinfo();
11013 } else if str_starts_with(cmd, "lspci" as ptr<u8>) == 1 {
11014 cmd_lspci();
11015 } else if str_starts_with(cmd, "ps" as ptr<u8>) == 1 {
11016 cmd_ps();
11017 } else if str_starts_with(cmd, "kill" as ptr<u8>) == 1 {
11018 cmd_kill();
11019 } else if str_starts_with(cmd, "ifconfig" as ptr<u8>) == 1 {
11020 cmd_ifconfig();
11021 } else if str_starts_with(cmd, "ping" as ptr<u8>) == 1 {
11022 cmd_ping();
11023 } else if str_starts_with(cmd, "ls" as ptr<u8>) == 1 {
11024 cmd_ls();
11025 } else if str_starts_with(cmd, "cat" as ptr<u8>) == 1 {
11026 cmd_cat();
11027 } else if str_starts_with(cmd, "touch" as ptr<u8>) == 1 {
11028 cmd_touch();
11029 } else if str_starts_with(cmd, "echo" as ptr<u8>) == 1 {
11030 cmd_echo();
11031 } else if str_starts_with(cmd, "dmesg" as ptr<u8>) == 1 {
11032 cmd_dmesg();
11033 } else if str_starts_with(cmd, "hexdump" as ptr<u8>) == 1 {
11034 let addr = parse_hex(get_arg(1));
11035 if addr == 0 {
11036 cmd_hexdump(0xB8000, 64);
11037 } else {
11038 cmd_hexdump(addr, 64);
11039 }
11040 } else if str_starts_with(cmd, "reboot" as ptr<u8>) == 1 {
11041 reboot();
11042 } else if str_starts_with(cmd, "poweroff" as ptr<u8>) == 1 {
11043 poweroff();
11044 } else {
11045 term_print("wsh: command not found: " as ptr<u8>, 0x0C);
11046 term_print(cmd, 0x0C);
11047 term_write_char(10);
11048 }
11049
11050 shell_idx = 0;
11051 shell_print_prompt();
11052 }
11053
11054 fn shell_process_key(c: u8) {
11055 if c == 10 {
11056 shell_execute();
11057 } else if c == 8 {
11058 if shell_idx > 0 {
11059 shell_idx = shell_idx - 1;
11060 shell_buffer[shell_idx] = 0;
11061 term_write_char(8);
11062 }
11063 } else {
11064 if shell_idx < 255 {
11065 shell_buffer[shell_idx] = c;
11066 shell_idx = shell_idx + 1;
11067 term_write_char(c);
11068 }
11069 }
11070 }
11071
11072 fn kernel_main() {
11073 term_clear();
11074 kbd_init();
11075 shell_init();
11076
11077 asm {
11078 "sti"
11079 }
11080
11081 loop {
11082 asm {
11083 "hlt"
11084 }
11085 }
11086 }

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