Wux Maskot

W OPERATING SYSTEM

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

Kuruluş Amblemi

SÜRÜM DETAYI: 0.0.2 Beta

Yayın Tarihi: 2026-07-06

Yama Notları:

W-Kernel v0.0.2 Beta Sürüm Notu

Bu sürümde, 64-bit Long Mode uyumlu 16 baytlık TSS tanımlayıcı yapısı düzeltilerek ltr aşamasındaki Triple Fault çökmesi giderilmiş, PMM bitmap algoritmasındaki 32-bit kaydırma taşması 1u64 tanımlamasıyla çözülmüştür. Ayrıca VMM tarafındaki sayfa tablosu erişim bayrakları ile kimlik haritalaması kararlı hale getirilmiş, spinlock mekanizması doğrudan donanım seviyesi atomik bayraklarla güçlendirilerek ACPI RSDP v2.0 genişletilmiş checksum doğrulamaları sisteme entegre edilmiş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 fn tcp_send_segment(sock: ptr<TcpSocket>, flags: u16, payload: ptr<u8>, payload_len: u16) {
2229 let tcp_len = sizeof(TcpHeader) as u16 + payload_len;
2230 let ip_len = sizeof(Ipv4Header) as u16 + tcp_len;
2231 let eth_len = sizeof(EthernetHeader) as u16 + ip_len;
2232
2233 let buffer = pmm_alloc_blocks(1) as ptr<u8>;
2234 memset(buffer, 0, eth_len as u64);
2235
2236 let eth = buffer as ptr<EthernetHeader>;
2237 for i in 0..6 { (*eth).dest_mac.addr[i] = 0xFF; }
2238 for i in 0..6 { (*eth).src_mac.addr[i] = system_mac.addr[i]; }
2239 (*eth).ethertype = htons(0x0800);
2240
2241 let iph = (buffer as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
2242 (*iph).ihl_version = 0x45;
2243 (*iph).tos = 0;
2244 (*iph).total_length = htons(ip_len);
2245 (*iph).id = htons(tcp_socket_count as u16);
2246 (*iph).flags_frag = 0;
2247 (*iph).ttl = 64;
2248 (*iph).protocol = 6;
2249 for i in 0..4 { (*iph).src_ip.addr[i] = system_ip.addr[i]; }
2250 for i in 0..4 { (*iph).dest_ip.addr[i] = (*sock).remote_ip.addr[i]; }
2251 (*iph).checksum = calculate_checksum(iph as ptr<u8>, sizeof(Ipv4Header) as u32);
2252
2253 let tcph = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
2254 (*tcph).src_port = htons((*sock).local_port);
2255 (*tcph).dest_port = htons((*sock).remote_port);
2256 (*tcph).seq_num = htonl((*sock).seq_num);
2257 (*tcph).ack_num = htonl((*sock).ack_num);
2258 (*tcph).data_offset_flags = htons((5 << 12) | flags);
2259 (*tcph).window_size = htons((*sock).window_size);
2260 (*tcph).urgent_ptr = 0;
2261
2262 let tcp_payload = (buffer as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64 + sizeof(TcpHeader) as u64) as ptr<u8>;
2263 if payload_len > 0 {
2264 memcpy(tcp_payload, payload, payload_len as u64);
2265 }
2266
2267 (*tcph).checksum = tcp_compute_checksum(system_ip, (*sock).remote_ip, tcp_len, tcph as ptr<u8>);
2268 rtl8139_send(buffer, eth_len as u32);
2269 pmm_free_blocks(buffer as u64, 1);
2270 }
2271 fn tcp_connect(sock: ptr<TcpSocket>, remote_ip: Ipv4Addr, remote_port: u16) {
2272 spin_lock(&((*sock).lock));
2273 (*sock).remote_ip = remote_ip;
2274 (*sock).remote_port = remote_port;
2275 if (*sock).local_port == 0 {
2276 (*sock).local_port = 49152 + (tcp_socket_count as u16 % 16384);
2277 }
2278 (*sock).seq_num = 0x11223344;
2279 (*sock).state = TCP_STATE_SYN_SENT;
2280 tcp_send_segment(sock, 0x0002, 0 as ptr<u8>, 0);
2281 spin_unlock(&((*sock).lock));
2282 }
2283 fn tcp_close(sock: ptr<TcpSocket>) {
2284 spin_lock(&((*sock).lock));
2285 if (*sock).state == TCP_STATE_ESTABLISHED || (*sock).state == TCP_STATE_SYN_RCVD {
2286 (*sock).state = TCP_STATE_FIN_WAIT_1;
2287 tcp_send_segment(sock, 0x0011, 0 as ptr<u8>, 0);
2288 } else {
2289 (*sock).state = TCP_STATE_CLOSED;
2290 (*sock).is_active = false;
2291 pmm_free_blocks((*sock).rx_buffer as u64, 2);
2292 pmm_free_blocks((*sock).tx_buffer as u64, 2);
2293 }
2294 spin_unlock(&((*sock).lock));
2295 }
2296 fn tcp_bind(sock: ptr<TcpSocket>, port: u16) {
2297 spin_lock(&((*sock).lock));
2298 (*sock).local_port = port;
2299 spin_unlock(&((*sock).lock));
2300 }
2301 fn tcp_listen(sock: ptr<TcpSocket>) {
2302 spin_lock(&((*sock).lock));
2303 (*sock).state = TCP_STATE_LISTEN;
2304 spin_unlock(&((*sock).lock));
2305 }
2306 struct Fat32ExtBPB {
2307 jmp: [u8; 3],
2308 oem_name: [u8; 8],
2309 bytes_per_sector: u16,
2310 sectors_per_cluster: u8,
2311 reserved_sector_count: u16,
2312 num_fats: u8,
2313 root_entry_count: u16,
2314 total_sectors_16: u16,
2315 media_type: u8,
2316 table_size_16: u16,
2317 sectors_per_track: u16,
2318 head_side_count: u16,
2319 hidden_sector_count: u32,
2320 total_sectors_32: u32,
2321 table_size_32: u32,
2322 extended_flags: u16,
2323 fat_version: u16,
2324 root_cluster: u32,
2325 fat_info: u16,
2326 backup_boot_sector: u16,
2327 reserved_0: [u8; 12],
2328 drive_number: u8,
2329 reserved_1: u8,
2330 boot_signature: u8,
2331 volume_id: u32,
2332 volume_label: [u8; 11],
2333 fat_type_label: [u8; 8],
2334 }
2335 struct Fat32DirEntry {
2336 name: [u8; 11],
2337 attr: u8,
2338 nt_res: u8,
2339 crt_time_tenth: u8,
2340 crt_time: u16,
2341 crt_date: u16,
2342 lst_acc_date: u16,
2343 fst_clus_hi: u16,
2344 wrt_time: u16,
2345 wrt_date: u16,
2346 fst_clus_lo: u16,
2347 file_size: u32,
2348 }
2349 let mut fat32_lba_start: u32 = 0;
2350 let mut fat32_fat_start: u32 = 0;
2351 let mut fat32_data_start: u32 = 0;
2352 let mut fat32_root_cluster: u32 = 0;
2353 let mut fat32_sectors_per_cluster: u32 = 0;
2354 let mut fat32_bytes_per_sector: u32 = 0;
2355 fn fat32_init(lba_offset: u32) {
2356 fat32_lba_start = lba_offset;
2357 let bpb_buf = pmm_alloc_blocks(1) as ptr<u8>;
2358 let bpb = bpb_buf as ptr<Fat32ExtBPB>;
2359 fat32_bytes_per_sector = (*bpb).bytes_per_sector as u32;
2360 fat32_sectors_per_cluster = (*bpb).sectors_per_cluster as u32;
2361 fat32_fat_start = fat32_lba_start + (*bpb).reserved_sector_count as u32;
2362 let fat_size = (*bpb).table_size_32;
2363 fat32_data_start = fat32_fat_start + ((*bpb).num_fats as u32 * fat_size);
2364 fat32_root_cluster = (*bpb).root_cluster;
2365 pmm_free_blocks(bpb_buf as u64, 1);
2366 }
2367 fn fat32_cluster_to_lba(cluster: u32) -> u32 {
2368 return fat32_data_start + ((cluster - 2) * fat32_sectors_per_cluster);
2369 }
2370 fn fat32_read_next_cluster(cluster: u32) -> u32 {
2371 let fat_offset = cluster * 4;
2372 let fat_sector = fat32_fat_start + (fat_offset / fat32_bytes_per_sector);
2373 let ent_offset = fat_offset % fat32_bytes_per_sector;
2374 let buf = pmm_alloc_blocks(1) as ptr<u8>;
2375 let next_cluster = *((buf as u64 + ent_offset as u64) as ptr<u32>) & 0x0FFFFFFF;
2376 pmm_free_blocks(buf as u64, 1);
2377 return next_cluster;
2378 }
2379 fn fat32_find_file(dir_cluster: u32, filename: ptr<u8>) -> ptr<Fat32DirEntry> {
2380 let mut current_cluster = dir_cluster;
2381 let buf = pmm_alloc_blocks(1) as ptr<u8>;
2382 while current_cluster < 0x0FFFFFF8 {
2383 let entries_per_cluster = (fat32_sectors_per_cluster * fat32_bytes_per_sector) / 32;
2384 for i in 0..entries_per_cluster {
2385 let entry = (buf as u64 + (i * 32) as u64) as ptr<Fat32DirEntry>;
2386 if (*entry).name[0] == 0x00 {
2387 pmm_free_blocks(buf as u64, 1);
2388 return 0 as ptr<Fat32DirEntry>;
2389 }
2390 if (*entry).name[0] != 0xE5 && ((*entry).attr & 0x0F) != 0x0F {
2391 let mut match_found = true;
2392 for j in 0..11 {
2393 if (*entry).name[j as usize] != *(filename + j) {
2394 match_found = false;
2395 break;
2396 }
2397 }
2398 if match_found {
2399 let ret_entry = pmm_alloc_blocks(1) as ptr<Fat32DirEntry>;
2400 memcpy(ret_entry as ptr<u8>, entry as ptr<u8>, 32);
2401 pmm_free_blocks(buf as u64, 1);
2402 return ret_entry;
2403 }
2404 }
2405 }
2406 current_cluster = fat32_read_next_cluster(current_cluster);
2407 }
2408 pmm_free_blocks(buf as u64, 1);
2409 return 0 as ptr<Fat32DirEntry>;
2410 }
2411 fn acpi_get_pm1_control() -> (u32, u32) {
2412 if acpi_fadt == 0 as ptr<FADTHeader> { return (0, 0); }
2413 let pm1a = (*acpi_fadt).pm1a_control_block;
2414 let pm1b = (*acpi_fadt).pm1b_control_block;
2415 return (pm1a, pm1b);
2416 }
2417 fn acpi_power_off() {
2418 let (pm1a, pm1b) = acpi_get_pm1_control();
2419 if pm1a != 0 {
2420 let val = inw(pm1a as u16);
2421 outw(pm1a as u16, val | (5 << 10) | (1 << 13));
2422 }
2423 if pm1b != 0 {
2424 let val = inw(pm1b as u16);
2425 outw(pm1b as u16, val | (5 << 10) | (1 << 13));
2426 }
2427 cpu_cli();
2428 loop { cpu_hlt(); }
2429 }
2430 fn acpi_reset() {
2431 let reset_reg = 0x64;
2432 let reset_cmd = 0xFE;
2433 while (inb(reset_reg) & 2) != 0 { cpu_pause(); }
2434 outb(reset_reg, reset_cmd);
2435 cpu_cli();
2436 loop { cpu_hlt(); }
2437 }
2438 fn gui_draw_checkbox(win: ptr<CompositorWindow>, x: u32, y: u32, checked: bool, label: ptr<u8>) {
2439 comp_draw_rect(win, x, y, 16, 16, 0xFFFFFF);
2440 comp_draw_rect(win, x+1, y+1, 14, 14, 0x222222);
2441 if checked {
2442 comp_draw_rect(win, x+4, y+4, 8, 8, 0x00FF00);
2443 }
2444 gui_draw_string(win, label, x + 24, y, 0xFFFFFF, 0xFFFFFFFF);
2445 }
2446 fn gui_draw_radio(win: ptr<CompositorWindow>, x: u32, y: u32, selected: bool, label: ptr<u8>) {
2447 comp_draw_rect(win, x, y, 16, 16, 0x888888);
2448 comp_draw_rect(win, x+2, y+2, 12, 12, 0x222222);
2449 if selected {
2450 comp_draw_rect(win, x+5, y+5, 6, 6, 0x00AFFF);
2451 }
2452 gui_draw_string(win, label, x + 24, y, 0xFFFFFF, 0xFFFFFFFF);
2453 }
2454 fn gui_draw_progressbar(win: ptr<CompositorWindow>, x: u32, y: u32, w: u32, h: u32, progress: u32, max: u32) {
2455 comp_draw_rect(win, x, y, w, h, 0x444444);
2456 comp_draw_rect(win, x+1, y+1, w-2, h-2, 0x111111);
2457 let mut fill_w = 0;
2458 if max > 0 {
2459 fill_w = (progress * (w - 2)) / max;
2460 }
2461 if fill_w > 0 {
2462 comp_draw_rect(win, x+1, y+1, fill_w, h-2, 0x00FF00);
2463 }
2464 }
2465 fn gui_draw_slider(win: ptr<CompositorWindow>, x: u32, y: u32, w: u32, val: u32, max: u32) {
2466 let h = 10;
2467 comp_draw_rect(win, x, y + 4, w, 2, 0x888888);
2468 let mut pos_x = 0;
2469 if max > 0 {
2470 pos_x = (val * w) / max;
2471 }
2472 if pos_x > w - 8 { pos_x = w - 8; }
2473 comp_draw_rect(win, x + pos_x, y, 8, h, 0xFFFFFF);
2474 }
2475 struct AudioMixerChannel {
2476 is_playing: bool,
2477 buffer: ptr<u8>,
2478 length: u32,
2479 position: u32,
2480 volume: u8,
2481 sample_rate: u32,
2482 }
2483 let mut global_audio_mixer: [AudioMixerChannel; 16];
2484 fn mixer_init() {
2485 for i in 0..16 {
2486 global_audio_mixer[i].is_playing = false;
2487 global_audio_mixer[i].position = 0;
2488 global_audio_mixer[i].volume = 128;
2489 }
2490 }
2491 fn mixer_play_pcm(buffer: ptr<u8>, length: u32, rate: u32) -> i32 {
2492 for i in 0..16 {
2493 if !global_audio_mixer[i].is_playing {
2494 global_audio_mixer[i].buffer = buffer;
2495 global_audio_mixer[i].length = length;
2496 global_audio_mixer[i].position = 0;
2497 global_audio_mixer[i].sample_rate = rate;
2498 global_audio_mixer[i].is_playing = true;
2499 return i as i32;
2500 }
2501 }
2502 return -1;
2503 }
2504 fn mixer_stop_channel(channel: u32) {
2505 if channel < 16 {
2506 global_audio_mixer[channel as usize].is_playing = false;
2507 }
2508 }
2509 fn mixer_process_frame(output_buffer: ptr<u16>, frames: u32) {
2510 for f in 0..frames {
2511 let mut mixed_sample_l: i32 = 0;
2512 let mut mixed_sample_r: i32 = 0;
2513 for c in 0..16 {
2514 let mut ch = &global_audio_mixer[c];
2515 if (*ch).is_playing && (*ch).position < (*ch).length {
2516 let sample_ptr = ((*ch).buffer as u64 + (*ch).position as u64 * 4) as ptr<i16>;
2517 let left = (*sample_ptr as i32 * (*ch).volume as i32) / 255;
2518 let right = (*(sample_ptr as u64 + 2) as ptr<i16> as i32 * (*ch).volume as i32) / 255;
2519 mixed_sample_l = mixed_sample_l + left;
2520 mixed_sample_r = mixed_sample_r + right;
2521 (*ch).position = (*ch).position + 1;
2522 } else if (*ch).is_playing {
2523 (*ch).is_playing = false;
2524 }
2525 }
2526 if mixed_sample_l > 32767 { mixed_sample_l = 32767; }
2527 if mixed_sample_l < -32768 { mixed_sample_l = -32768; }
2528 if mixed_sample_r > 32767 { mixed_sample_r = 32767; }
2529 if mixed_sample_r < -32768 { mixed_sample_r = -32768; }
2530
2531 *(output_buffer as u64 + f as u64 * 4) as ptr<i16> = mixed_sample_l as i16;
2532 *(output_buffer as u64 + f as u64 * 4 + 2) as ptr<i16> = mixed_sample_r as i16;
2533 }
2534 }
2535 let mut usb_hid_kbd_map: [u8; 128] = [
2536 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,
2537 '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,
2538 '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,
2539 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,
2540 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,
2541 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
2542 ];
2543 let mut usb_hid_shift_map: [u8; 128] = [
2544 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,
2545 '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,
2546 '!' as u8, '@' as u8, '#' as u8, '$' as u8, '%' as u8, '^' as u8, '&' as u8, '*' as u8, '(' as u8, ')' as u8,
2547 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,
2548 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,
2549 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
2550 ];
2551 struct UsbDeviceDescriptor {
2552 length: u8,
2553 descriptor_type: u8,
2554 bcd_usb: u16,
2555 device_class: u8,
2556 device_subclass: u8,
2557 device_protocol: u8,
2558 max_packet_size: u8,
2559 id_vendor: u16,
2560 id_product: u16,
2561 bcd_device: u16,
2562 manufacturer: u8,
2563 product: u8,
2564 serial_number: u8,
2565 num_configurations: u8,
2566 }
2567 struct UsbEndpointDescriptor {
2568 length: u8,
2569 descriptor_type: u8,
2570 endpoint_address: u8,
2571 attributes: u8,
2572 max_packet_size: u16,
2573 interval: u8,
2574 }
2575 struct HidReport {
2576 modifier: u8,
2577 reserved: u8,
2578 keys: [u8; 6],
2579 }
2580 struct MouseReport {
2581 buttons: u8,
2582 x: i8,
2583 y: i8,
2584 wheel: i8,
2585 }
2586 let mut global_kbd_state_shift: bool = false;
2587 let mut global_kbd_state_caps: bool = false;
2588 fn usb_hid_parse_keyboard(report: ptr<HidReport>) {
2589 let m = (*report).modifier;
2590 global_kbd_state_shift = (m & 0x02) != 0 || (m & 0x20) != 0;
2591
2592 for i in 0..6 {
2593 let k = (*report).keys[i];
2594 if k >= 4 && k <= 100 {
2595 let mut ascii = usb_hid_kbd_map[k as usize];
2596 if global_kbd_state_shift != global_kbd_state_caps {
2597 if k >= 4 && k <= 29 { ascii = usb_hid_shift_map[k as usize]; }
2598 }
2599 if global_kbd_state_shift && (k < 4 || k > 29) {
2600 ascii = usb_hid_shift_map[k as usize];
2601 }
2602 if ascii != 0 {
2603 kbd_buf[kbd_wp as usize] = ascii;
2604 kbd_wp = (kbd_wp + 1) % 1024;
2605 }
2606 }
2607 }
2608 }
2609 fn usb_hid_parse_mouse(report: ptr<MouseReport>) {
2610 let btn = (*report).buttons;
2611 let dx = (*report).x as i32;
2612 let dy = (*report).y as i32;
2613
2614 mouse_x = mouse_x + dx;
2615 mouse_y = mouse_y + dy;
2616
2617 if mouse_x < 0 { mouse_x = 0; }
2618 if mouse_y < 0 { mouse_y = 0; }
2619 if mouse_x >= comp_width as i32 { mouse_x = comp_width as i32 - 1; }
2620 if mouse_y >= comp_height as i32 { mouse_y = comp_height as i32 - 1; }
2621
2622 mouse_b = btn;
2623 }
2624 const SWAP_MAGIC: u64 = 0x5357415053504143;
2625 const MAX_SWAP_PAGES: u64 = 262144;
2626 struct SwapHeader {
2627 magic: u64,
2628 total_pages: u64,
2629 free_pages: u64,
2630 bitmap_offset: u64,
2631 }
2632 struct PageFrameInfo {
2633 phys_addr: u64,
2634 virt_addr: u64,
2635 pid: u64,
2636 access_time: u64,
2637 flags: u32,
2638 swap_idx: u64,
2639 }
2640 let mut swap_bitmap: ptr<u64>;
2641 let mut pfn_database: ptr<PageFrameInfo>;
2642 let mut pfn_count: u64 = 0;
2643 let mut current_time_tick: u64 = 0;
2644 let mut swap_lck: Spinlock;
2645 fn swap_init() {
2646 spin_init(&swap_lck);
2647 let bitmap_sz = MAX_SWAP_PAGES / 64 * 8;
2648 swap_bitmap = pmm_alloc_blocks(bitmap_sz / PAGE_SIZE + 1) as ptr<u64>;
2649 memset(swap_bitmap as ptr<u8>, 0, bitmap_sz);
2650
2651 let pfn_sz = (MAX_MEM_MB * 1024 * 1024) / PAGE_SIZE * sizeof(PageFrameInfo) as u64;
2652 pfn_database = pmm_alloc_blocks(pfn_sz / PAGE_SIZE + 1) as ptr<PageFrameInfo>;
2653 memset(pfn_database as ptr<u8>, 0, pfn_sz);
2654 }
2655 fn swap_alloc_slot() -> u64 {
2656 for i in 0..(MAX_SWAP_PAGES / 64) {
2657 if *(swap_bitmap + i) != 0xFFFFFFFFFFFFFFFF {
2658 for j in 0..64 {
2659 if (*(swap_bitmap + i) & (1 << j)) == 0 {
2660 *(swap_bitmap + i) |= 1 << j;
2661 return i * 64 + j;
2662 }
2663 }
2664 }
2665 }
2666 return 0xFFFFFFFFFFFFFFFF;
2667 }
2668 fn swap_free_slot(idx: u64) {
2669 *(swap_bitmap + (idx / 64)) &= !(1 << (idx % 64));
2670 }
2671 fn page_replacement_lru() -> ptr<PageFrameInfo> {
2672 let mut oldest_time: u64 = 0xFFFFFFFFFFFFFFFF;
2673 let mut victim: ptr<PageFrameInfo> = 0 as ptr<PageFrameInfo>;
2674
2675 for i in 0..pfn_count {
2676 let frame = (pfn_database as u64 + i * sizeof(PageFrameInfo) as u64) as ptr<PageFrameInfo>;
2677 if ((*frame).flags & 1) != 0 && ((*frame).flags & 2) == 0 {
2678 if (*frame).access_time < oldest_time {
2679 oldest_time = (*frame).access_time;
2680 victim = frame;
2681 }
2682 }
2683 }
2684 return victim;
2685 }
2686 fn swap_page_out(frame: ptr<PageFrameInfo>) -> bool {
2687 spin_lock(&swap_lck);
2688 let slot = swap_alloc_slot();
2689 if slot == 0xFFFFFFFFFFFFFFFF {
2690 spin_unlock(&swap_lck);
2691 return false;
2692 }
2693
2694 let disk_lba = 1000000 + (slot * 8);
2695 (*frame).swap_idx = slot;
2696 (*frame).flags &= !1;
2697 vmm_unmap_page((*frame).virt_addr);
2698
2699 spin_unlock(&swap_lck);
2700 return true;
2701 }
2702 fn swap_page_in(frame: ptr<PageFrameInfo>) {
2703 spin_lock(&swap_lck);
2704 let phys = pmm_alloc_blocks(1);
2705 if phys == 0 {
2706 let victim = page_replacement_lru();
2707 if victim != 0 as ptr<PageFrameInfo> {
2708 swap_page_out(victim);
2709 }
2710 }
2711
2712 let disk_lba = 1000000 + ((*frame).swap_idx * 8);
2713 (*frame).phys_addr = phys;
2714 (*frame).flags |= 1;
2715 vmm_map_page(phys, (*frame).virt_addr, 0x07);
2716 swap_free_slot((*frame).swap_idx);
2717 spin_unlock(&swap_lck);
2718 }
2719 fn page_fault_handler_adv(cr2: u64, err_code: u64) {
2720 let virt_align = cr2 & !(PAGE_SIZE - 1);
2721 for i in 0..pfn_count {
2722 let frame = (pfn_database as u64 + i * sizeof(PageFrameInfo) as u64) as ptr<PageFrameInfo>;
2723 if (*frame).virt_addr == virt_align && ((*frame).flags & 1) == 0 {
2724 swap_page_in(frame);
2725 return;
2726 }
2727 }
2728 cpu_cli();
2729 loop { cpu_hlt(); }
2730 }
2731 struct Vec3 { x: f32, y: f32, z: f32, w: f32 }
2732 struct Mat4 { m: [[f32; 4]; 4] }
2733 fn math_abs(a: f32) -> f32 { if a < 0.0 { return -a; } return a; }
2734 fn math_fmod(a: f32, b: f32) -> f32 {
2735 let mut res = a;
2736 while res >= b { res = res - b; }
2737 while res < 0.0 { res = res + b; }
2738 return res;
2739 }
2740 fn taylor_sin(mut x: f32) -> f32 {
2741 let PI2 = 6.28318530718;
2742 x = math_fmod(x, PI2);
2743 if x > 3.14159265 { x = x - PI2; }
2744 let x2 = x * x;
2745 let x3 = x2 * x;
2746 let x5 = x3 * x2;
2747 let x7 = x5 * x2;
2748 return x - (x3 / 6.0) + (x5 / 120.0) - (x7 / 5040.0);
2749 }
2750 fn taylor_cos(mut x: f32) -> f32 {
2751 let PI2 = 6.28318530718;
2752 x = math_fmod(x, PI2);
2753 if x > 3.14159265 { x = x - PI2; }
2754 let x2 = x * x;
2755 let x4 = x2 * x2;
2756 let x6 = x4 * x2;
2757 return 1.0 - (x2 / 2.0) + (x4 / 24.0) - (x6 / 720.0);
2758 }
2759 fn mat4_identity() -> Mat4 {
2760 let mut mat: Mat4;
2761 for i in 0..4 { for j in 0..4 { mat.m[i][j] = 0.0; } }
2762 mat.m[0][0] = 1.0; mat.m[1][1] = 1.0; mat.m[2][2] = 1.0; mat.m[3][3] = 1.0;
2763 return mat;
2764 }
2765 fn mat4_mul(a: ptr<Mat4>, b: ptr<Mat4>) -> Mat4 {
2766 let mut res: Mat4;
2767 for c in 0..4 {
2768 for r in 0..4 {
2769 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];
2770 }
2771 }
2772 return res;
2773 }
2774 fn mat4_make_rot_x(angle: f32) -> Mat4 {
2775 let mut mat = mat4_identity();
2776 let c = taylor_cos(angle); let s = taylor_sin(angle);
2777 mat.m[1][1] = c; mat.m[1][2] = -s;
2778 mat.m[2][1] = s; mat.m[2][2] = c;
2779 return mat;
2780 }
2781 fn mat4_make_rot_y(angle: f32) -> Mat4 {
2782 let mut mat = mat4_identity();
2783 let c = taylor_cos(angle); let s = taylor_sin(angle);
2784 mat.m[0][0] = c; mat.m[0][2] = s;
2785 mat.m[2][0] = -s; mat.m[2][2] = c;
2786 return mat;
2787 }
2788 fn mat4_make_rot_z(angle: f32) -> Mat4 {
2789 let mut mat = mat4_identity();
2790 let c = taylor_cos(angle); let s = taylor_sin(angle);
2791 mat.m[0][0] = c; mat.m[0][1] = -s;
2792 mat.m[1][0] = s; mat.m[1][1] = c;
2793 return mat;
2794 }
2795 fn mat4_make_proj(fov: f32, aspect: f32, near: f32, far: f32) -> Mat4 {
2796 let f = 1.0 / taylor_sin(fov * 0.5) / taylor_cos(fov * 0.5);
2797 let mut mat: Mat4;
2798 for i in 0..4 { for j in 0..4 { mat.m[i][j] = 0.0; } }
2799 mat.m[0][0] = f / aspect;
2800 mat.m[1][1] = f;
2801 mat.m[2][2] = far / (far - near);
2802 mat.m[2][3] = (-far * near) / (far - near);
2803 mat.m[3][2] = 1.0;
2804 return mat;
2805 }
2806 fn mat4_multiply_vec(m: ptr<Mat4>, i: ptr<Vec3>) -> Vec3 {
2807 let mut v: Vec3;
2808 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];
2809 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];
2810 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];
2811 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];
2812 return v;
2813 }
2814 struct Triangle3D { p: [Vec3; 3], color: u32 }
2815 struct Mesh3D { tris: ptr<Triangle3D>, count: u32 }
2816 let mut z_buffer: ptr<f32>;
2817 fn render_init_3d(w: u32, h: u32) {
2818 z_buffer = pmm_alloc_blocks((w * h * 4) / PAGE_SIZE + 1) as ptr<f32>;
2819 }
2820 fn render_clear_z_buffer(w: u32, h: u32) {
2821 for i in 0..(w * h) { *(z_buffer as u64 + i as u64 * 4) as ptr<f32> = 0.0; }
2822 }
2823 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) {
2824 let mut min_y = y0; if y1 < min_y { min_y = y1; } if y2 < min_y { min_y = y2; }
2825 let mut max_y = y0; if y1 > max_y { max_y = y1; } if y2 > max_y { max_y = y2; }
2826 let mut min_x = x0; if x1 < min_x { min_x = x1; } if x2 < min_x { min_x = x2; }
2827 let mut max_x = x0; if x1 > max_x { max_x = x1; } if x2 > max_x { max_x = x2; }
2828 if min_x < 0 { min_x = 0; }
2829 if min_y < 0 { min_y = 0; }
2830 if max_x >= (*win).width as i32 { max_x = (*win).width as i32 - 1; }
2831 if max_y >= (*win).height as i32 { max_y = (*win).height as i32 - 1; }
2832 let buf = (*win).buffer_phys as ptr<u32>;
2833 let z_ptr = z_buffer;
2834 for y in min_y..=max_y {
2835 for x in min_x..=max_x {
2836 let w0 = ((x1 - x0) * (y - y0) - (y1 - y0) * (x - x0)) as f32;
2837 let w1 = ((x2 - x1) * (y - y1) - (y2 - y1) * (x - x1)) as f32;
2838 let w2 = ((x0 - x2) * (y - y2) - (y0 - y2) * (x - x2)) as f32;
2839 if (w0 >= 0.0 && w1 >= 0.0 && w2 >= 0.0) || (w0 <= 0.0 && w1 <= 0.0 && w2 <= 0.0) {
2840 let area = w0 + w1 + w2;
2841 let b0 = w1 / area; let b1 = w2 / area; let b2 = w0 / area;
2842 let z = z0 * b0 + z1 * b1 + z2 * b2;
2843 let z_idx = (y * (*win).width as i32 + x) as u64;
2844 let current_z = *(z_ptr as u64 + z_idx * 4) as ptr<f32>;
2845 if z > *current_z {
2846 *current_z = z;
2847 *(buf + z_idx) = color;
2848 }
2849 }
2850 }
2851 }
2852 }
2853 fn render_mesh(win: ptr<CompositorWindow>, mesh: ptr<Mesh3D>, mat_world: ptr<Mat4>, mat_proj: ptr<Mat4>) {
2854 for i in 0..(*mesh).count {
2855 let tri = ((*mesh).tris as u64 + i as u64 * sizeof(Triangle3D) as u64) as ptr<Triangle3D>;
2856 let mut tri_proj: Triangle3D;
2857 let mut tri_trans: Triangle3D;
2858
2859 for j in 0..3 {
2860 tri_trans.p[j] = mat4_multiply_vec(mat_world, &(*tri).p[j] as ptr<Vec3>);
2861 tri_proj.p[j] = mat4_multiply_vec(mat_proj, &tri_trans.p[j] as ptr<Vec3>);
2862
2863 if tri_proj.p[j].w != 0.0 {
2864 tri_proj.p[j].x = tri_proj.p[j].x / tri_proj.p[j].w;
2865 tri_proj.p[j].y = tri_proj.p[j].y / tri_proj.p[j].w;
2866 tri_proj.p[j].z = tri_proj.p[j].z / tri_proj.p[j].w;
2867 }
2868
2869 tri_proj.p[j].x = (tri_proj.p[j].x + 1.0) * 0.5 * (*win).width as f32;
2870 tri_proj.p[j].y = (tri_proj.p[j].y + 1.0) * 0.5 * (*win).height as f32;
2871 }
2872
2873 let normal_x = (tri_trans.p[1].y - tri_trans.p[0].y) * (tri_trans.p[2].z - tri_trans.p[0].z) - (tri_trans.p[1].z - tri_trans.p[0].z) * (tri_trans.p[2].y - tri_trans.p[0].y);
2874 let normal_y = (tri_trans.p[1].z - tri_trans.p[0].z) * (tri_trans.p[2].x - tri_trans.p[0].x) - (tri_trans.p[1].x - tri_trans.p[0].x) * (tri_trans.p[2].z - tri_trans.p[0].z);
2875 let normal_z = (tri_trans.p[1].x - tri_trans.p[0].x) * (tri_trans.p[2].y - tri_trans.p[0].y) - (tri_trans.p[1].y - tri_trans.p[0].y) * (tri_trans.p[2].x - tri_trans.p[0].x);
2876
2877 if normal_x * tri_trans.p[0].x + normal_y * tri_trans.p[0].y + normal_z * tri_trans.p[0].z < 0.0 {
2878 let shade = math_abs(normal_z) * 255.0;
2879 let c_r = (((*tri).color >> 16) & 0xFF) as f32 * shade / 255.0;
2880 let c_g = (((*tri).color >> 8) & 0xFF) as f32 * shade / 255.0;
2881 let c_b = ((*tri).color & 0xFF) as f32 * shade / 255.0;
2882 let shaded_color = ((c_r as u32) << 16) | ((c_g as u32) << 8) | (c_b as u32);
2883
2884 draw_flat_triangle(win, tri_proj.p[0].x as i32, tri_proj.p[0].y as i32, tri_proj.p[0].z,
2885 tri_proj.p[1].x as i32, tri_proj.p[1].y as i32, tri_proj.p[1].z,
2886 tri_proj.p[2].x as i32, tri_proj.p[2].y as i32, tri_proj.p[2].z, shaded_color);
2887 }
2888 }
2889 }
2890 let mut prng_state: u64 = 0x8817263544132211;
2891 fn rand_next() -> u64 {
2892 prng_state ^= prng_state << 13;
2893 prng_state ^= prng_state >> 7;
2894 prng_state ^= prng_state << 17;
2895 return prng_state;
2896 }
2897 fn rand_seed(seed: u64) {
2898 if seed != 0 { prng_state = seed; }
2899 }
2900 fn strchr(str: ptr<u8>, c: u8) -> ptr<u8> {
2901 let mut i: u64 = 0;
2902 while *(str + i) != 0 {
2903 if *(str + i) == c { return (str as u64 + i) as ptr<u8>; }
2904 i = i + 1;
2905 }
2906 if c == 0 { return (str as u64 + i) as ptr<u8>; }
2907 return 0 as ptr<u8>;
2908 }
2909 fn strcat(dest: ptr<u8>, src: ptr<u8>) {
2910 let mut i: u64 = 0;
2911 while *(dest + i) != 0 { i = i + 1; }
2912 let mut j: u64 = 0;
2913 while *(src + j) != 0 {
2914 *(dest + i + j) = *(src + j);
2915 j = j + 1;
2916 }
2917 *(dest + i + j) = 0;
2918 }
2919 fn strncmp(s1: ptr<u8>, s2: ptr<u8>, n: u64) -> i32 {
2920 for i in 0..n {
2921 if *(s1 + i) == 0 || *(s1 + i) != *(s2 + i) {
2922 return (*(s1 + i) - *(s2 + i)) as i32;
2923 }
2924 }
2925 return 0;
2926 }
2927 fn atoi(str: ptr<u8>) -> i32 {
2928 let mut res: i32 = 0;
2929 let mut sign: i32 = 1;
2930 let mut i: u64 = 0;
2931 if *(str + i) == '-' as u8 {
2932 sign = -1;
2933 i = i + 1;
2934 }
2935 while *(str + i) >= '0' as u8 && *(str + i) <= '9' as u8 {
2936 res = res * 10 + (*(str + i) - '0' as u8) as i32;
2937 i = i + 1;
2938 }
2939 return res * sign;
2940 }
2941 fn itoa(val: i32, base: i32, buf: ptr<u8>) {
2942 let mut i: u64 = 0;
2943 let mut is_neg = false;
2944 let mut num = val;
2945 if num == 0 {
2946 *(buf + i) = '0' as u8;
2947 *(buf + i + 1) = 0;
2948 return;
2949 }
2950 if num < 0 && base == 10 {
2951 is_neg = true;
2952 num = -num;
2953 }
2954 while num != 0 {
2955 let rem = num % base;
2956 if rem > 9 {
2957 *(buf + i) = (rem - 10 + 'a' as i32) as u8;
2958 } else {
2959 *(buf + i) = (rem + '0' as i32) as u8;
2960 }
2961 i = i + 1;
2962 num = num / base;
2963 }
2964 if is_neg {
2965 *(buf + i) = '-' as u8;
2966 i = i + 1;
2967 }
2968 *(buf + i) = 0;
2969 let mut start: u64 = 0;
2970 let mut end: u64 = i - 1;
2971 while start < end {
2972 let temp = *(buf + start);
2973 *(buf + start) = *(buf + end);
2974 *(buf + end) = temp;
2975 start = start + 1;
2976 end = end - 1;
2977 }
2978 }
2979 let mut b64_table: ptr<u8> = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" as ptr<u8>;
2980 fn base64_encode(src: ptr<u8>, len: u64, out: ptr<u8>) {
2981 let mut i: u64 = 0;
2982 let mut j: u64 = 0;
2983 while i < len {
2984 let octet_a = if i < len { *(src + i) } else { 0 };
2985 let octet_b = if i + 1 < len { *(src + i + 1) } else { 0 };
2986 let octet_c = if i + 2 < len { *(src + i + 2) } else { 0 };
2987 let triple = ((octet_a as u32) << 16) + ((octet_b as u32) << 8) + (octet_c as u32);
2988 *(out + j) = *(b64_table + ((triple >> 18) & 0x3F) as u64);
2989 *(out + j + 1) = *(b64_table + ((triple >> 12) & 0x3F) as u64);
2990 *(out + j + 2) = if i + 1 < len { *(b64_table + ((triple >> 6) & 0x3F) as u64) } else { '=' as u8 };
2991 *(out + j + 3) = if i + 2 < len { *(b64_table + (triple & 0x3F) as u64) } else { '=' as u8 };
2992 i = i + 3;
2993 j = j + 4;
2994 }
2995 *(out + j) = 0;
2996 }
2997 fn tcp_accept(sock: ptr<TcpSocket>) -> ptr<TcpSocket> {
2998 spin_lock(&((*sock).lock));
2999 if (*sock).state == TCP_STATE_SYN_RCVD {
3000 let new_sock = tcp_create_socket();
3001 if new_sock != 0 as ptr<TcpSocket> {
3002 (*new_sock).state = TCP_STATE_ESTABLISHED;
3003 (*new_sock).local_port = (*sock).local_port;
3004 (*new_sock).remote_port = (*sock).remote_port;
3005 (*new_sock).remote_ip = (*sock).remote_ip;
3006 (*new_sock).seq_num = (*sock).seq_num;
3007 (*new_sock).ack_num = (*sock).ack_num;
3008 (*sock).state = TCP_STATE_LISTEN;
3009 spin_unlock(&((*sock).lock));
3010 return new_sock;
3011 }
3012 }
3013 spin_unlock(&((*sock).lock));
3014 return 0 as ptr<TcpSocket>;
3015 }
3016 fn tcp_receive(sock: ptr<TcpSocket>, buffer: ptr<u8>, max_len: u32) -> u32 {
3017 spin_lock(&((*sock).lock));
3018 let mut bytes_read: u32 = 0;
3019 while (*sock).rx_head != (*sock).rx_tail && bytes_read < max_len {
3020 *(buffer + bytes_read as u64) = *((*sock).rx_buffer as u64 + (*sock).rx_tail as u64) as ptr<u8>;
3021 (*sock).rx_tail = ((*sock).rx_tail + 1) % (PAGE_SIZE as u32 * 2);
3022 bytes_read = bytes_read + 1;
3023 }
3024 spin_unlock(&((*sock).lock));
3025 return bytes_read;
3026 }
3027 fn tcp_send_data(sock: ptr<TcpSocket>, data: ptr<u8>, len: u32) {
3028 spin_lock(&((*sock).lock));
3029 if (*sock).state == TCP_STATE_ESTABLISHED {
3030 tcp_send_segment(sock, 0x0018, data, len as u16);
3031 (*sock).seq_num = (*sock).seq_num + len;
3032 }
3033 spin_unlock(&((*sock).lock));
3034 }
3035 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>;
3036 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>;
3037 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>;
3038 fn http_handle_client(client_sock: ptr<TcpSocket>) {
3039 let req_buf = pmm_alloc_blocks(1) as ptr<u8>;
3040 memset(req_buf, 0, PAGE_SIZE);
3041 let mut wait_timeout = 10000;
3042 let mut req_len: u32 = 0;
3043 while wait_timeout > 0 {
3044 let r = tcp_receive(client_sock, (req_buf as u64 + req_len as u64) as ptr<u8>, PAGE_SIZE as u32 - req_len);
3045 req_len = req_len + r;
3046 if req_len > 4 {
3047 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 {
3048 break;
3049 }
3050 }
3051 wait_timeout = wait_timeout - 1;
3052 cpu_pause();
3053 }
3054
3055 if req_len > 0 {
3056 if strncmp(req_buf, "GET / " as ptr<u8>, 6) == 0 {
3057 let res_buf = pmm_alloc_blocks(2) as ptr<u8>;
3058 memset(res_buf, 0, PAGE_SIZE * 2);
3059 strcpy(res_buf, http_200_hdr);
3060 strcat(res_buf, http_index_html);
3061 tcp_send_data(client_sock, res_buf, strlen(res_buf) as u32);
3062 pmm_free_blocks(res_buf as u64, 2);
3063 } else {
3064 let res_buf = pmm_alloc_blocks(1) as ptr<u8>;
3065 memset(res_buf, 0, PAGE_SIZE);
3066 strcpy(res_buf, http_404_hdr);
3067 strcat(res_buf, "<html><body><h1>404 File Not Found</h1></body></html>" as ptr<u8>);
3068 tcp_send_data(client_sock, res_buf, strlen(res_buf) as u32);
3069 pmm_free_blocks(res_buf as u64, 1);
3070 }
3071 }
3072
3073 tcp_close(client_sock);
3074 pmm_free_blocks(req_buf as u64, 1);
3075 (*current_process).state = 0;
3076 scheduler_tick();
3077 }
3078 fn http_server_task() {
3079 let server_sock = tcp_create_socket();
3080 tcp_bind(server_sock, 80);
3081 tcp_listen(server_sock);
3082
3083 loop {
3084 let client_sock = tcp_accept(server_sock);
3085 if client_sock != 0 as ptr<TcpSocket> {
3086 let proc = create_process(http_handle_client as u64, true);
3087 let ctx = (*proc).context;
3088 (*ctx).rdi = client_sock as u64;
3089 }
3090 scheduler_tick();
3091 }
3092 }
3093 struct ShellCtx {
3094 win: ptr<CompositorWindow>,
3095 cx: u32,
3096 cy: u32,
3097 buf: [u8; 512],
3098 pos: u32,
3099 cwd: [u8; 256],
3100 fg_color: u32,
3101 }
3102 let mut global_shell: ptr<ShellCtx>;
3103 fn shell_print_char(c: u8) {
3104 if c == 10 {
3105 (*global_shell).cx = 2;
3106 (*global_shell).cy = (*global_shell).cy + system_font_h + 2;
3107 } else if c == 8 {
3108 if (*global_shell).cx > 2 {
3109 (*global_shell).cx = (*global_shell).cx - system_font_w;
3110 gui_draw_char((*global_shell).win, ' ' as u8, (*global_shell).cx, (*global_shell).cy, (*global_shell).fg_color, 0x000000);
3111 }
3112 } else {
3113 gui_draw_char((*global_shell).win, c, (*global_shell).cx, (*global_shell).cy, (*global_shell).fg_color, 0x000000);
3114 (*global_shell).cx = (*global_shell).cx + system_font_w;
3115 if (*global_shell).cx >= (*(*global_shell).win).width - system_font_w {
3116 (*global_shell).cx = 2;
3117 (*global_shell).cy = (*global_shell).cy + system_font_h + 2;
3118 }
3119 }
3120 if (*global_shell).cy >= (*(*global_shell).win).height - system_font_h {
3121 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
3122 (*global_shell).cx = 2;
3123 (*global_shell).cy = 2;
3124 }
3125 }
3126 fn shell_print_string(str: ptr<u8>) {
3127 let mut i: u64 = 0;
3128 while *(str + i) != 0 {
3129 shell_print_char(*(str + i));
3130 i = i + 1;
3131 }
3132 }
3133 fn shell_draw_prompt() {
3134 (*global_shell).fg_color = 0x00FF00;
3135 shell_print_string("root@aegis-x:" as ptr<u8>);
3136 (*global_shell).fg_color = 0x00AFFF;
3137 shell_print_string(&((*global_shell).cwd[0]) as ptr<u8>);
3138 (*global_shell).fg_color = 0xFFFFFF;
3139 shell_print_string("# " as ptr<u8>);
3140 }
3141 fn shell_cmd_clear() {
3142 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
3143 (*global_shell).cx = 2;
3144 (*global_shell).cy = 2;
3145 }
3146 fn shell_cmd_help() {
3147 shell_print_string("Aegis-X Shell v1.0\n" as ptr<u8>);
3148 shell_print_string("Commands: help, clear, echo, ls, cat, uptime, reboot, poweroff\n" as ptr<u8>);
3149 }
3150 fn shell_cmd_echo(args: ptr<u8>) {
3151 shell_print_string(args);
3152 shell_print_char(10);
3153 }
3154 fn shell_cmd_uptime() {
3155 let mut buf: [u8; 32];
3156 let ticks = rtc_tick;
3157 shell_print_string("Uptime: " as ptr<u8>);
3158 itoa(ticks as i32, 10, &buf[0] as ptr<u8>);
3159 shell_print_string(&buf[0] as ptr<u8>);
3160 shell_print_string(" ticks\n" as ptr<u8>);
3161 }
3162 fn shell_cmd_ls(args: ptr<u8>) {
3163 let mut path = &((*global_shell).cwd[0]) as ptr<u8>;
3164 if *args != 0 { path = args; }
3165 let dir = vfs_find_child(global_vfs_root, path);
3166 if dir == 0 as ptr<VfsNode> {
3167 shell_print_string("ls: cannot access path\n" as ptr<u8>);
3168 return;
3169 }
3170 if ((*dir).flags & 0x07) != 0 {
3171 let mut curr = (*dir).children;
3172 while curr != 0 as ptr<VfsNode> {
3173 if ((*curr).flags & 0x07) != 0 {
3174 (*global_shell).fg_color = 0x00AFFF;
3175 } else {
3176 (*global_shell).fg_color = 0xFFFFFF;
3177 }
3178 shell_print_string(&((*curr).name[0]) as ptr<u8>);
3179 shell_print_string(" " as ptr<u8>);
3180 curr = (*curr).next;
3181 }
3182 shell_print_char(10);
3183 } else {
3184 shell_print_string(&((*dir).name[0]) as ptr<u8>);
3185 shell_print_char(10);
3186 }
3187 (*global_shell).fg_color = 0xFFFFFF;
3188 }
3189 fn shell_execute() {
3190 let mut cmd_buf: [u8; 512];
3191 memcpy(&cmd_buf[0] as ptr<u8>, &((*global_shell).buf[0]) as ptr<u8>, (*global_shell).pos as u64);
3192 cmd_buf[(*global_shell).pos as usize] = 0;
3193
3194 let mut i: u32 = 0;
3195 while cmd_buf[i as usize] != 0 && cmd_buf[i as usize] != ' ' as u8 { i = i + 1; }
3196 if cmd_buf[i as usize] == ' ' as u8 {
3197 cmd_buf[i as usize] = 0;
3198 i = i + 1;
3199 }
3200 let args = (&cmd_buf[0] as u64 + i as u64) as ptr<u8>;
3201 let cmd = &cmd_buf[0] as ptr<u8>;
3202
3203 if (*global_shell).pos > 0 {
3204 if strcmp(cmd, "help" as ptr<u8>) == 0 { shell_cmd_help(); }
3205 else if strcmp(cmd, "clear" as ptr<u8>) == 0 { shell_cmd_clear(); }
3206 else if strcmp(cmd, "echo" as ptr<u8>) == 0 { shell_cmd_echo(args); }
3207 else if strcmp(cmd, "uptime" as ptr<u8>) == 0 { shell_cmd_uptime(); }
3208 else if strcmp(cmd, "ls" as ptr<u8>) == 0 { shell_cmd_ls(args); }
3209 else if strcmp(cmd, "reboot" as ptr<u8>) == 0 { acpi_reset(); }
3210 else if strcmp(cmd, "poweroff" as ptr<u8>) == 0 { acpi_power_off(); }
3211 else {
3212 shell_print_string("Command not found: " as ptr<u8>);
3213 shell_print_string(cmd);
3214 shell_print_char(10);
3215 }
3216 }
3217
3218 (*global_shell).pos = 0;
3219 shell_draw_prompt();
3220 }
3221 fn shell_task() {
3222 let win = comp_create_window(50, 50, 800, 600, "Aegis Terminal" as ptr<u8>);
3223 comp_draw_rect(win, 0, 0, (*win).width, (*win).height, 0x000000);
3224
3225 global_shell = pmm_alloc_blocks(1) as ptr<ShellCtx>;
3226 memset(global_shell as ptr<u8>, 0, sizeof(ShellCtx) as u64);
3227 (*global_shell).win = win;
3228 (*global_shell).cx = 2;
3229 (*global_shell).cy = 2;
3230 (*global_shell).fg_color = 0xFFFFFF;
3231 strcpy(&((*global_shell).cwd[0]) as ptr<u8>, "/" as ptr<u8>);
3232
3233 shell_print_string("Welcome to YBG13 Aegis-X Terminal.\n" as ptr<u8>);
3234 shell_draw_prompt();
3235
3236 loop {
3237 let c = kbd_read();
3238 if c != 0 {
3239 if c == 10 {
3240 shell_print_char(10);
3241 shell_execute();
3242 } else if c == 8 {
3243 if (*global_shell).pos > 0 {
3244 (*global_shell).pos = (*global_shell).pos - 1;
3245 shell_print_char(8);
3246 }
3247 } else {
3248 if (*global_shell).pos < 510 {
3249 (*global_shell).buf[(*global_shell).pos as usize] = c;
3250 (*global_shell).pos = (*global_shell).pos + 1;
3251 shell_print_char(c);
3252 }
3253 }
3254 }
3255 scheduler_tick();
3256 }
3257 }
3258 struct VmaNode {
3259 start_vaddr: u64,
3260 end_vaddr: u64,
3261 flags: u32,
3262 file_node: ptr<VfsNode>,
3263 file_offset: u64,
3264 next: ptr<VmaNode>,
3265 }
3266 struct ProcessMemoryMap {
3267 vma_head: ptr<VmaNode>,
3268 brk_start: u64,
3269 brk_current: u64,
3270 stack_bottom: u64,
3271 stack_top: u64,
3272 mmap_base: u64,
3273 }
3274 fn vma_create(proc_map: ptr<ProcessMemoryMap>, start: u64, len: u64, flags: u32, file: ptr<VfsNode>, offset: u64) -> ptr<VmaNode> {
3275 let node = pmm_alloc_blocks(1) as ptr<VmaNode>;
3276 memset(node as ptr<u8>, 0, sizeof(VmaNode) as u64);
3277 (*node).start_vaddr = start;
3278 (*node).end_vaddr = start + len;
3279 (*node).flags = flags;
3280 (*node).file_node = file;
3281 (*node).file_offset = offset;
3282
3283 if (*proc_map).vma_head == 0 as ptr<VmaNode> {
3284 (*proc_map).vma_head = node;
3285 } else {
3286 let mut curr = (*proc_map).vma_head;
3287 while (*curr).next != 0 as ptr<VmaNode> {
3288 curr = (*curr).next;
3289 }
3290 (*curr).next = node;
3291 }
3292 return node;
3293 }
3294 fn vma_find_region(proc_map: ptr<ProcessMemoryMap>, vaddr: u64) -> ptr<VmaNode> {
3295 let mut curr = (*proc_map).vma_head;
3296 while curr != 0 as ptr<VmaNode> {
3297 if vaddr >= (*curr).start_vaddr && vaddr < (*curr).end_vaddr {
3298 return curr;
3299 }
3300 curr = (*curr).next;
3301 }
3302 return 0 as ptr<VmaNode>;
3303 }
3304 struct TarHeader {
3305 filename: [u8; 100],
3306 filemode: [u8; 8],
3307 owner_id: [u8; 8],
3308 group_id: [u8; 8],
3309 filesize: [u8; 12],
3310 last_mod: [u8; 12],
3311 checksum: [u8; 8],
3312 type_flag: u8,
3313 linked_file: [u8; 100],
3314 ustar_magic: [u8; 6],
3315 ustar_version: [u8; 2],
3316 owner_name: [u8; 32],
3317 group_name: [u8; 32],
3318 dev_major: [u8; 8],
3319 dev_minor: [u8; 8],
3320 prefix: [u8; 155],
3321 padding: [u8; 12],
3322 }
3323 fn tar_octal_to_int(octal_str: ptr<u8>, len: u32) -> u64 {
3324 let mut result: u64 = 0;
3325 for i in 0..len {
3326 let c = *(octal_str + i as u64);
3327 if c >= '0' as u8 && c <= '7' as u8 {
3328 result = result * 8 + (c - '0' as u8) as u64;
3329 } else {
3330 break;
3331 }
3332 }
3333 return result;
3334 }
3335 fn tar_extract_initramfs(ramfs_base: u64, ramfs_size: u64) {
3336 let mut current_offset: u64 = 0;
3337 while current_offset < ramfs_size {
3338 let header = (ramfs_base + current_offset) as ptr<TarHeader>;
3339 if (*header).filename[0] == 0 { break; }
3340
3341 let size_val = tar_octal_to_int(&((*header).filesize[0]) as ptr<u8>, 11);
3342 let mode_val = tar_octal_to_int(&((*header).filemode[0]) as ptr<u8>, 7);
3343 let mut name_buf: [u8; 256];
3344 memset(&name_buf[0] as ptr<u8>, 0, 256);
3345
3346 if (*header).prefix[0] != 0 {
3347 strcpy(&name_buf[0] as ptr<u8>, &((*header).prefix[0]) as ptr<u8>);
3348 strcat(&name_buf[0] as ptr<u8>, "/" as ptr<u8>);
3349 }
3350 strcat(&name_buf[0] as ptr<u8>, &((*header).filename[0]) as ptr<u8>);
3351
3352 let file_data_ptr = ramfs_base + current_offset + 512;
3353
3354 if (*header).type_flag == '0' as u8 || (*header).type_flag == 0 {
3355 let mut fd: FileDescriptor;
3356 let node = vfs_create_node(global_vfs_root, &name_buf[0] as ptr<u8>, 0x06);
3357 (*node).ptr = file_data_ptr;
3358 (*node).length = size_val;
3359 (*node).uid = 0;
3360 (*node).gid = 0;
3361 } else if (*header).type_flag == '5' as u8 {
3362 vfs_create_node(global_vfs_root, &name_buf[0] as ptr<u8>, 0x07);
3363 }
3364
3365 let aligned_size = (size_val + 511) & !511;
3366 current_offset = current_offset + 512 + aligned_size;
3367 }
3368 }
3369 const REG_TYPE_INT: u32 = 1;
3370 const REG_TYPE_STR: u32 = 2;
3371 const REG_TYPE_BIN: u32 = 3;
3372 struct RegistryNode {
3373 key_name: [u8; 64],
3374 val_type: u32,
3375 val_int: u64,
3376 val_str: [u8; 256],
3377 val_bin: ptr<u8>,
3378 bin_len: u64,
3379 parent: ptr<RegistryNode>,
3380 child: ptr<RegistryNode>,
3381 next: ptr<RegistryNode>,
3382 }
3383 let mut global_registry_root: ptr<RegistryNode>;
3384 fn registry_init() {
3385 global_registry_root = pmm_alloc_blocks(1) as ptr<RegistryNode>;
3386 memset(global_registry_root as ptr<u8>, 0, sizeof(RegistryNode) as u64);
3387 strcpy(&((*global_registry_root).key_name[0]) as ptr<u8>, "ROOT" as ptr<u8>);
3388 }
3389 fn registry_create_key(parent: ptr<RegistryNode>, name: ptr<u8>) -> ptr<RegistryNode> {
3390 let node = pmm_alloc_blocks(1) as ptr<RegistryNode>;
3391 memset(node as ptr<u8>, 0, sizeof(RegistryNode) as u64);
3392 strcpy(&((*node).key_name[0]) as ptr<u8>, name);
3393 (*node).parent = parent;
3394
3395 if (*parent).child == 0 as ptr<RegistryNode> {
3396 (*parent).child = node;
3397 } else {
3398 let mut curr = (*parent).child;
3399 while (*curr).next != 0 as ptr<RegistryNode> {
3400 curr = (*curr).next;
3401 }
3402 (*curr).next = node;
3403 }
3404 return node;
3405 }
3406 fn registry_find_key(parent: ptr<RegistryNode>, name: ptr<u8>) -> ptr<RegistryNode> {
3407 let mut curr = (*parent).child;
3408 while curr != 0 as ptr<RegistryNode> {
3409 if strcmp(&((*curr).key_name[0]) as ptr<u8>, name) == 0 {
3410 return curr;
3411 }
3412 curr = (*curr).next;
3413 }
3414 return 0 as ptr<RegistryNode>;
3415 }
3416 fn registry_set_int(node: ptr<RegistryNode>, val: u64) {
3417 (*node).val_type = REG_TYPE_INT;
3418 (*node).val_int = val;
3419 }
3420 fn registry_set_str(node: ptr<RegistryNode>, val: ptr<u8>) {
3421 (*node).val_type = REG_TYPE_STR;
3422 strcpy(&((*node).val_str[0]) as ptr<u8>, val);
3423 }
3424 fn registry_set_bin(node: ptr<RegistryNode>, val: ptr<u8>, len: u64) {
3425 (*node).val_type = REG_TYPE_BIN;
3426 if (*node).val_bin != 0 as ptr<u8> {
3427 pmm_free_blocks((*node).val_bin as u64, ((*node).bin_len / PAGE_SIZE) + 1);
3428 }
3429 (*node).val_bin = pmm_alloc_blocks((len / PAGE_SIZE) + 1) as ptr<u8>;
3430 memcpy((*node).val_bin, val, len);
3431 (*node).bin_len = len;
3432 }
3433 struct UserAccount {
3434 uid: u32,
3435 gid: u32,
3436 username: [u8; 32],
3437 pass_hash: [u8; 32],
3438 pass_salt: [u8; 16],
3439 home_dir: [u8; 64],
3440 shell_path: [u8; 64],
3441 next: ptr<UserAccount>,
3442 }
3443 let mut global_user_db: ptr<UserAccount>;
3444 let mut next_uid: u32 = 1000;
3445 fn auth_init_system() {
3446 global_user_db = 0 as ptr<UserAccount>;
3447 let mut root_salt: [u8; 16];
3448 for i in 0..16 { root_salt[i] = (rand_next() & 0xFF) as u8; }
3449 auth_create_user("root" as ptr<u8>, "aegis_admin" as ptr<u8>, 0, 0, "/root" as ptr<u8>, "/bin/shell" as ptr<u8>);
3450 }
3451 fn auth_generate_hash(password: ptr<u8>, salt: ptr<u8>, out_hash: ptr<u8>) {
3452 let mut pass_len = strlen(password);
3453 let mut buffer: [u8; 128];
3454 memset(&buffer[0] as ptr<u8>, 0, 128);
3455 memcpy(&buffer[0] as ptr<u8>, password, pass_len);
3456 memcpy((&buffer[0] as u64 + pass_len) as ptr<u8>, salt, 16);
3457
3458 let mut ctx: Sha256Ctx;
3459 sha256_init(&ctx);
3460 sha256_transform(&ctx, &buffer[0] as ptr<u8>);
3461
3462 for iter in 0..999 {
3463 let mut temp_ctx: Sha256Ctx;
3464 sha256_init(&temp_ctx);
3465 let state_ptr = &ctx.state[0] as ptr<u32> as ptr<u8>;
3466 sha256_transform(&temp_ctx, state_ptr);
3467 for i in 0..8 { ctx.state[i] = temp_ctx.state[i]; }
3468 }
3469
3470 let state_ptr = &ctx.state[0] as ptr<u32> as ptr<u8>;
3471 for i in 0..32 {
3472 *(out_hash + i) = *(state_ptr + i);
3473 }
3474 }
3475 fn auth_create_user(username: ptr<u8>, password: ptr<u8>, uid_force: u32, gid: u32, home: ptr<u8>, shell: ptr<u8>) -> ptr<UserAccount> {
3476 let new_user = pmm_alloc_blocks(1) as ptr<UserAccount>;
3477 memset(new_user as ptr<u8>, 0, sizeof(UserAccount) as u64);
3478
3479 strcpy(&((*new_user).username[0]) as ptr<u8>, username);
3480 strcpy(&((*new_user).home_dir[0]) as ptr<u8>, home);
3481 strcpy(&((*new_user).shell_path[0]) as ptr<u8>, shell);
3482
3483 if uid_force != 0xFFFFFFFF {
3484 (*new_user).uid = uid_force;
3485 } else {
3486 (*new_user).uid = next_uid;
3487 next_uid = next_uid + 1;
3488 }
3489 (*new_user).gid = gid;
3490
3491 for i in 0..16 { (*new_user).pass_salt[i] = (rand_next() & 0xFF) as u8; }
3492 auth_generate_hash(password, &((*new_user).pass_salt[0]) as ptr<u8>, &((*new_user).pass_hash[0]) as ptr<u8>);
3493
3494 (*new_user).next = global_user_db;
3495 global_user_db = new_user;
3496 return new_user;
3497 }
3498 fn auth_verify_login(username: ptr<u8>, password: ptr<u8>) -> ptr<UserAccount> {
3499 let mut curr = global_user_db;
3500 while curr != 0 as ptr<UserAccount> {
3501 if strcmp(&((*curr).username[0]) as ptr<u8>, username) == 0 {
3502 let mut test_hash: [u8; 32];
3503 auth_generate_hash(password, &((*curr).pass_salt[0]) as ptr<u8>, &test_hash[0] as ptr<u8>);
3504 if memcmp(&((*curr).pass_hash[0]) as ptr<u8>, &test_hash[0] as ptr<u8>, 32) == 0 {
3505 return curr;
3506 } else {
3507 return 0 as ptr<UserAccount>;
3508 }
3509 }
3510 curr = (*curr).next;
3511 }
3512 return 0 as ptr<UserAccount>;
3513 }
3514 struct ServiceDaemon {
3515 name: [u8; 64],
3516 exec_path: [u8; 128],
3517 pid: u64,
3518 status: u32,
3519 runlevel: u32,
3520 restart_count: u32,
3521 deps: [u64; 8],
3522 dep_count: u32,
3523 next: ptr<ServiceDaemon>,
3524 }
3525 const SRV_STATUS_STOPPED: u32 = 0;
3526 const SRV_STATUS_STARTING: u32 = 1;
3527 const SRV_STATUS_RUNNING: u32 = 2;
3528 const SRV_STATUS_FAILED: u32 = 3;
3529 let mut global_service_list: ptr<ServiceDaemon>;
3530 let mut init_current_runlevel: u32 = 0;
3531 fn init_register_service(name: ptr<u8>, path: ptr<u8>, runlevel: u32) -> ptr<ServiceDaemon> {
3532 let srv = pmm_alloc_blocks(1) as ptr<ServiceDaemon>;
3533 memset(srv as ptr<u8>, 0, sizeof(ServiceDaemon) as u64);
3534 strcpy(&((*srv).name[0]) as ptr<u8>, name);
3535 strcpy(&((*srv).exec_path[0]) as ptr<u8>, path);
3536 (*srv).status = SRV_STATUS_STOPPED;
3537 (*srv).runlevel = runlevel;
3538 (*srv).dep_count = 0;
3539
3540 (*srv).next = global_service_list;
3541 global_service_list = srv;
3542 return srv;
3543 }
3544 fn init_add_dependency(srv: ptr<ServiceDaemon>, target_name: ptr<u8>) {
3545 let mut curr = global_service_list;
3546 while curr != 0 as ptr<ServiceDaemon> {
3547 if strcmp(&((*curr).name[0]) as ptr<u8>, target_name) == 0 {
3548 if (*srv).dep_count < 8 {
3549 (*srv).deps[(*srv).dep_count as usize] = curr as u64;
3550 (*srv).dep_count = (*srv).dep_count + 1;
3551 }
3552 return;
3553 }
3554 curr = (*curr).next;
3555 }
3556 }
3557 fn init_start_service(srv: ptr<ServiceDaemon>) -> bool {
3558 if (*srv).status == SRV_STATUS_RUNNING { return true; }
3559
3560 for i in 0..(*srv).dep_count {
3561 let dep = (*srv).deps[i as usize] as ptr<ServiceDaemon>;
3562 if (*dep).status != SRV_STATUS_RUNNING {
3563 if !init_start_service(dep) {
3564 (*srv).status = SRV_STATUS_FAILED;
3565 return false;
3566 }
3567 }
3568 }
3569
3570 (*srv).status = SRV_STATUS_STARTING;
3571 let pid = execve_ring3(&((*srv).exec_path[0]) as ptr<u8>, 0, 0);
3572 if pid != 0 {
3573 (*srv).pid = pid;
3574 (*srv).status = SRV_STATUS_RUNNING;
3575 return true;
3576 } else {
3577 (*srv).status = SRV_STATUS_FAILED;
3578 return false;
3579 }
3580 }
3581 fn init_set_runlevel(level: u32) {
3582 init_current_runlevel = level;
3583 let mut curr = global_service_list;
3584 while curr != 0 as ptr<ServiceDaemon> {
3585 if (*curr).runlevel <= level && (*curr).status == SRV_STATUS_STOPPED {
3586 init_start_service(curr);
3587 } else if (*curr).runlevel > level && (*curr).status == SRV_STATUS_RUNNING {
3588 let mut proc = process_queue;
3589 while proc != 0 as ptr<ProcessControlBlock> {
3590 if (*proc).pid == (*curr).pid {
3591 (*proc).state = 0;
3592 (*curr).status = SRV_STATUS_STOPPED;
3593 break;
3594 }
3595 proc = (*proc).next;
3596 }
3597 }
3598 curr = (*curr).next;
3599 }
3600 }
3601 fn init_monitor_loop() {
3602 loop {
3603 let mut curr = global_service_list;
3604 while curr != 0 as ptr<ServiceDaemon> {
3605 if (*curr).status == SRV_STATUS_RUNNING {
3606 let mut is_alive = false;
3607 let mut proc = process_queue;
3608 while proc != 0 as ptr<ProcessControlBlock> {
3609 if (*proc).pid == (*curr).pid && (*proc).state == 1 {
3610 is_alive = true;
3611 break;
3612 }
3613 proc = (*proc).next;
3614 }
3615 if !is_alive {
3616 (*curr).status = SRV_STATUS_FAILED;
3617 (*curr).restart_count = (*curr).restart_count + 1;
3618 if (*curr).restart_count < 5 {
3619 init_start_service(curr);
3620 }
3621 }
3622 }
3623 curr = (*curr).next;
3624 }
3625 for i in 0..100000 { cpu_pause(); }
3626 scheduler_tick();
3627 }
3628 }
3629 struct Ext2Superblock {
3630 s_inodes_count: u32,
3631 s_blocks_count: u32,
3632 s_r_blocks_count: u32,
3633 s_free_blocks_count: u32,
3634 s_free_inodes_count: u32,
3635 s_first_data_block: u32,
3636 s_log_block_size: u32,
3637 s_log_frag_size: i32,
3638 s_blocks_per_group: u32,
3639 s_frags_per_group: u32,
3640 s_inodes_per_group: u32,
3641 s_mtime: u32,
3642 s_wtime: u32,
3643 s_mnt_count: u16,
3644 s_max_mnt_count: i16,
3645 s_magic: u16,
3646 s_state: u16,
3647 s_errors: u16,
3648 s_minor_rev_level: u16,
3649 s_lastcheck: u32,
3650 s_checkinterval: u32,
3651 s_creator_os: u32,
3652 s_rev_level: u32,
3653 s_def_resuid: u16,
3654 s_def_resgid: u16,
3655 s_first_ino: u32,
3656 s_inode_size: u16,
3657 s_block_group_nr: u16,
3658 s_feature_compat: u32,
3659 s_feature_incompat: u32,
3660 s_feature_ro_compat: u32,
3661 s_uuid: [u8; 16],
3662 s_volume_name: [u8; 16],
3663 s_last_mounted: [u8; 64],
3664 s_algo_bitmap: u32,
3665 }
3666 struct Ext2BlockGroupDesc {
3667 bg_block_bitmap: u32,
3668 bg_inode_bitmap: u32,
3669 bg_inode_table: u32,
3670 bg_free_blocks_count: u16,
3671 bg_free_inodes_count: u16,
3672 bg_used_dirs_count: u16,
3673 bg_pad: u16,
3674 bg_reserved: [u32; 3],
3675 }
3676 struct Ext2Inode {
3677 i_mode: u16,
3678 i_uid: u16,
3679 i_size: u32,
3680 i_atime: u32,
3681 i_ctime: u32,
3682 i_mtime: u32,
3683 i_dtime: u32,
3684 i_gid: u16,
3685 i_links_count: u16,
3686 i_blocks: u32,
3687 i_flags: u32,
3688 i_osd1: u32,
3689 i_block: [u32; 15],
3690 i_generation: u32,
3691 i_file_acl: u32,
3692 i_dir_acl: u32,
3693 i_faddr: u32,
3694 i_osd2: [u32; 3],
3695 }
3696 struct Ext2DirEntry {
3697 inode: u32,
3698 rec_len: u16,
3699 name_len: u8,
3700 file_type: u8,
3701 }
3702 let mut ext2_sb: ptr<Ext2Superblock>;
3703 let mut ext2_bgdt: ptr<Ext2BlockGroupDesc>;
3704 let mut ext2_block_size: u32 = 0;
3705 let mut ext2_inodes_per_group: u32 = 0;
3706 let mut ext2_inode_size: u32 = 0;
3707 let mut ext2_partition_base: u64 = 0;
3708 fn ext2_read_block(block_num: u32, buf: ptr<u8>) {
3709 let offset = ext2_partition_base + (block_num as u64 * ext2_block_size as u64);
3710 let dev_fd = pmm_alloc_blocks(1) as ptr<FileDescriptor>;
3711 (*dev_fd).node = vfs_find_child(global_vfs_root, "dev/sda1" as ptr<u8>);
3712 (*dev_fd).offset = offset;
3713 vfs_read(dev_fd, buf, ext2_block_size as u64);
3714 pmm_free_blocks(dev_fd as u64, 1);
3715 }
3716 fn ext2_init(partition_base: u64) {
3717 ext2_partition_base = partition_base;
3718 let sb_buf = pmm_alloc_blocks(1) as ptr<u8>;
3719 let dev_fd = pmm_alloc_blocks(1) as ptr<FileDescriptor>;
3720 (*dev_fd).node = vfs_find_child(global_vfs_root, "dev/sda1" as ptr<u8>);
3721 (*dev_fd).offset = ext2_partition_base + 1024;
3722 vfs_read(dev_fd, sb_buf, 1024);
3723
3724 ext2_sb = sb_buf as ptr<Ext2Superblock>;
3725 if (*ext2_sb).s_magic != 0xEF53 {
3726 pmm_free_blocks(sb_buf as u64, 1);
3727 pmm_free_blocks(dev_fd as u64, 1);
3728 return;
3729 }
3730
3731 ext2_block_size = 1024 << (*ext2_sb).s_log_block_size;
3732 ext2_inodes_per_group = (*ext2_sb).s_inodes_per_group;
3733 if (*ext2_sb).s_rev_level == 0 {
3734 ext2_inode_size = 128;
3735 } else {
3736 ext2_inode_size = (*ext2_sb).s_inode_size as u32;
3737 }
3738
3739 let bgdt_block = if ext2_block_size == 1024 { 2 } else { 1 };
3740 let bgdt_buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
3741 ext2_read_block(bgdt_block, bgdt_buf);
3742 ext2_bgdt = bgdt_buf as ptr<Ext2BlockGroupDesc>;
3743
3744 pmm_free_blocks(dev_fd as u64, 1);
3745 }
3746 fn ext2_get_inode(inode_num: u32, out_inode: ptr<Ext2Inode>) {
3747 let bg_idx = (inode_num - 1) / ext2_inodes_per_group;
3748 let local_idx = (inode_num - 1) % ext2_inodes_per_group;
3749 let bgd = (ext2_bgdt as u64 + bg_idx as u64 * sizeof(Ext2BlockGroupDesc) as u64) as ptr<Ext2BlockGroupDesc>;
3750
3751 let inode_table_block = (*bgd).bg_inode_table;
3752 let byte_offset = local_idx * ext2_inode_size;
3753 let block_offset = byte_offset / ext2_block_size;
3754 let internal_offset = byte_offset % ext2_block_size;
3755
3756 let target_block = inode_table_block + block_offset;
3757 let buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
3758 ext2_read_block(target_block, buf);
3759
3760 memcpy(out_inode as ptr<u8>, (buf as u64 + internal_offset as u64) as ptr<u8>, sizeof(Ext2Inode) as u64);
3761 pmm_free_blocks(buf as u64, (ext2_block_size / PAGE_SIZE as u32) + 1);
3762 }
3763 fn ext2_read_inode_data(inode: ptr<Ext2Inode>, buf: ptr<u8>) {
3764 let blocks_to_read = ((*inode).i_size + ext2_block_size - 1) / ext2_block_size;
3765 let mut current_block = 0;
3766 while current_block < blocks_to_read && current_block < 12 {
3767 let physical_block = (*inode).i_block[current_block as usize];
3768 if physical_block != 0 {
3769 ext2_read_block(physical_block, (buf as u64 + current_block as u64 * ext2_block_size as u64) as ptr<u8>);
3770 }
3771 current_block = current_block + 1;
3772 }
3773 }
3774 struct Elf64_Sym {
3775 st_name: u32,
3776 st_info: u8,
3777 st_other: u8,
3778 st_shndx: u16,
3779 st_value: u64,
3780 st_size: u64,
3781 }
3782 struct Elf64_Rela {
3783 r_offset: u64,
3784 r_info: u64,
3785 r_addend: i64,
3786 }
3787 struct Elf64_Dyn {
3788 d_tag: u64,
3789 d_val: u64,
3790 }
3791 const DT_NULL: u64 = 0;
3792 const DT_NEEDED: u64 = 1;
3793 const DT_PLTRELSZ: u64 = 2;
3794 const DT_PLTGOT: u64 = 3;
3795 const DT_HASH: u64 = 4;
3796 const DT_STRTAB: u64 = 5;
3797 const DT_SYMTAB: u64 = 6;
3798 const DT_RELA: u64 = 7;
3799 const DT_RELASZ: u64 = 8;
3800 const DT_RELAENT: u64 = 9;
3801 const DT_STRSZ: u64 = 10;
3802 const DT_SYMENT: u64 = 11;
3803 const R_X86_64_NONE: u64 = 0;
3804 const R_X86_64_64: u64 = 1;
3805 const R_X86_64_PC32: u64 = 2;
3806 const R_X86_64_GOT32: u64 = 3;
3807 const R_X86_64_PLT32: u64 = 4;
3808 const R_X86_64_COPY: u64 = 5;
3809 const R_X86_64_GLOB_DAT: u64 = 6;
3810 const R_X86_64_JUMP_SLOT: u64 = 7;
3811 const R_X86_64_RELATIVE: u64 = 8;
3812 fn elf_resolve_dynamic(load_base: u64, dyn_table: ptr<Elf64_Dyn>) {
3813 let mut strtab: ptr<u8> = 0 as ptr<u8>;
3814 let mut symtab: ptr<Elf64_Sym> = 0 as ptr<Elf64_Sym>;
3815 let mut rela: ptr<Elf64_Rela> = 0 as ptr<Elf64_Rela>;
3816 let mut relasz: u64 = 0;
3817
3818 let mut curr = dyn_table;
3819 while (*curr).d_tag != DT_NULL {
3820 if (*curr).d_tag == DT_STRTAB { strtab = (load_base + (*curr).d_val) as ptr<u8>; }
3821 else if (*curr).d_tag == DT_SYMTAB { symtab = (load_base + (*curr).d_val) as ptr<Elf64_Sym>; }
3822 else if (*curr).d_tag == DT_RELA { rela = (load_base + (*curr).d_val) as ptr<Elf64_Rela>; }
3823 else if (*curr).d_tag == DT_RELASZ { relasz = (*curr).d_val; }
3824 curr = (curr as u64 + sizeof(Elf64_Dyn) as u64) as ptr<Elf64_Dyn>;
3825 }
3826
3827 if rela != 0 as ptr<Elf64_Rela> && symtab != 0 as ptr<Elf64_Sym> {
3828 let rela_count = relasz / sizeof(Elf64_Rela) as u64;
3829 for i in 0..rela_count {
3830 let rel = (rela as u64 + i * sizeof(Elf64_Rela) as u64) as ptr<Elf64_Rela>;
3831 let r_type = (*rel).r_info & 0xFFFFFFFF;
3832 let sym_idx = (*rel).r_info >> 32;
3833 let target_addr = (load_base + (*rel).r_offset) as ptr<u64>;
3834
3835 if r_type == R_X86_64_RELATIVE {
3836 *target_addr = (load_base as i64 + (*rel).r_addend) as u64;
3837 } else if r_type == R_X86_64_GLOB_DAT || r_type == R_X86_64_JUMP_SLOT || r_type == R_X86_64_64 {
3838 let sym = (symtab as u64 + sym_idx * sizeof(Elf64_Sym) as u64) as ptr<Elf64_Sym>;
3839 let sym_val = (*sym).st_value;
3840 if sym_val != 0 {
3841 *target_addr = (load_base + sym_val) as i64 as u64 + (*rel).r_addend as u64;
3842 }
3843 }
3844 }
3845 }
3846 }
3847 struct AnsiState {
3848 in_escape: bool,
3849 in_bracket: bool,
3850 params: [u32; 8],
3851 param_count: u32,
3852 current_param: u32,
3853 saved_x: u32,
3854 saved_y: u32,
3855 }
3856 let mut global_ansi_state: AnsiState;
3857 fn ansi_init() {
3858 global_ansi_state.in_escape = false;
3859 global_ansi_state.in_bracket = false;
3860 global_ansi_state.param_count = 0;
3861 global_ansi_state.current_param = 0;
3862 global_ansi_state.saved_x = 0;
3863 global_ansi_state.saved_y = 0;
3864 }
3865 fn ansi_apply_colors() {
3866 for i in 0..global_ansi_state.param_count {
3867 let p = global_ansi_state.params[i as usize];
3868 if p == 0 {
3869 (*global_shell).fg_color = 0xFFFFFF;
3870 } else if p >= 30 && p <= 37 {
3871 if p == 30 { (*global_shell).fg_color = 0x000000; }
3872 else if p == 31 { (*global_shell).fg_color = 0xFF0000; }
3873 else if p == 32 { (*global_shell).fg_color = 0x00FF00; }
3874 else if p == 33 { (*global_shell).fg_color = 0xFFFF00; }
3875 else if p == 34 { (*global_shell).fg_color = 0x0000FF; }
3876 else if p == 35 { (*global_shell).fg_color = 0xFF00FF; }
3877 else if p == 36 { (*global_shell).fg_color = 0x00FFFF; }
3878 else if p == 37 { (*global_shell).fg_color = 0xFFFFFF; }
3879 }
3880 }
3881 }
3882 fn ansi_process_char(c: u8) -> bool {
3883 if c == 27 {
3884 global_ansi_state.in_escape = true;
3885 global_ansi_state.in_bracket = false;
3886 global_ansi_state.param_count = 0;
3887 global_ansi_state.current_param = 0;
3888 return true;
3889 }
3890 if global_ansi_state.in_escape {
3891 if !global_ansi_state.in_bracket {
3892 if c == '[' as u8 {
3893 global_ansi_state.in_bracket = true;
3894 } else {
3895 global_ansi_state.in_escape = false;
3896 }
3897 return true;
3898 }
3899
3900 if c >= '0' as u8 && c <= '9' as u8 {
3901 global_ansi_state.current_param = global_ansi_state.current_param * 10 + (c - '0' as u8) as u32;
3902 return true;
3903 } else if c == ';' as u8 {
3904 if global_ansi_state.param_count < 8 {
3905 global_ansi_state.params[global_ansi_state.param_count as usize] = global_ansi_state.current_param;
3906 global_ansi_state.param_count = global_ansi_state.param_count + 1;
3907 }
3908 global_ansi_state.current_param = 0;
3909 return true;
3910 } else {
3911 if global_ansi_state.param_count < 8 {
3912 global_ansi_state.params[global_ansi_state.param_count as usize] = global_ansi_state.current_param;
3913 global_ansi_state.param_count = global_ansi_state.param_count + 1;
3914 }
3915
3916 if c == 'm' as u8 {
3917 ansi_apply_colors();
3918 } else if c == 'H' as u8 || c == 'f' as u8 {
3919 let row = if global_ansi_state.param_count > 0 { global_ansi_state.params[0] } else { 1 };
3920 let col = if global_ansi_state.param_count > 1 { global_ansi_state.params[1] } else { 1 };
3921 (*global_shell).cx = col * system_font_w;
3922 (*global_shell).cy = row * system_font_h;
3923 } else if c == 'J' as u8 {
3924 if global_ansi_state.params[0] == 2 {
3925 comp_draw_rect((*global_shell).win, 0, 0, (*(*global_shell).win).width, (*(*global_shell).win).height, 0x000000);
3926 (*global_shell).cx = 2; (*global_shell).cy = 2;
3927 }
3928 }
3929
3930 global_ansi_state.in_escape = false;
3931 return true;
3932 }
3933 }
3934 return false;
3935 }
3936 struct ShmSegment {
3937 shm_id: u64,
3938 key: u32,
3939 size: u64,
3940 phys_base: u64,
3941 ref_count: u32,
3942 owner_pid: u64,
3943 permissions: u32,
3944 }
3945 let mut global_shm_table: [ShmSegment; 256];
3946 let mut shm_next_id: u64 = 100;
3947 let mut shm_lock: Spinlock;
3948 fn shm_init() {
3949 spin_init(&shm_lock);
3950 for i in 0..256 {
3951 global_shm_table[i].shm_id = 0;
3952 }
3953 }
3954 fn shm_create(key: u32, size: u64, permissions: u32, pid: u64) -> u64 {
3955 spin_lock(&shm_lock);
3956 for i in 0..256 {
3957 if global_shm_table[i].key == key && global_shm_table[i].shm_id != 0 {
3958 spin_unlock(&shm_lock);
3959 return global_shm_table[i].shm_id;
3960 }
3961 }
3962
3963 for i in 0..256 {
3964 if global_shm_table[i].shm_id == 0 {
3965 let pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
3966 let phys = pmm_alloc_blocks(pages);
3967 memset(phys as ptr<u8>, 0, pages * PAGE_SIZE);
3968
3969 global_shm_table[i].shm_id = shm_next_id;
3970 shm_next_id = shm_next_id + 1;
3971 global_shm_table[i].key = key;
3972 global_shm_table[i].size = size;
3973 global_shm_table[i].phys_base = phys;
3974 global_shm_table[i].ref_count = 0;
3975 global_shm_table[i].owner_pid = pid;
3976 global_shm_table[i].permissions = permissions;
3977
3978 spin_unlock(&shm_lock);
3979 return global_shm_table[i].shm_id;
3980 }
3981 }
3982 spin_unlock(&shm_lock);
3983 return 0;
3984 }
3985 fn shm_attach(shm_id: u64, cr3: u64, vaddr_suggest: u64) -> u64 {
3986 spin_lock(&shm_lock);
3987 for i in 0..256 {
3988 if global_shm_table[i].shm_id == shm_id {
3989 let pages = (global_shm_table[i].size + PAGE_SIZE - 1) / PAGE_SIZE;
3990 let mut vaddr = vaddr_suggest;
3991 if vaddr == 0 { vaddr = 0x5000000000; }
3992
3993 let old_cr3 = rdmsr(0);
3994 asm { "mov cr3, %0" in "%0" = cr3; }
3995 for p in 0..pages {
3996 vmm_map_page(global_shm_table[i].phys_base + p * PAGE_SIZE, vaddr + p * PAGE_SIZE, 0x07);
3997 }
3998 asm { "mov cr3, %0" in "%0" = old_cr3; }
3999
4000 global_shm_table[i].ref_count = global_shm_table[i].ref_count + 1;
4001 spin_unlock(&shm_lock);
4002 return vaddr;
4003 }
4004 }
4005 spin_unlock(&shm_lock);
4006 return 0;
4007 }
4008 struct ProcessStat {
4009 pid: u64,
4010 state: u8,
4011 time_slice: u64,
4012 vram_usage: u64,
4013 name: [u8; 32],
4014 }
4015 fn get_system_stats(out_stats: ptr<ProcessStat>, max_count: u32) -> u32 {
4016 let mut count = 0;
4017 let mut curr = process_queue;
4018 while curr != 0 as ptr<ProcessControlBlock> && count < max_count {
4019 let stat = (out_stats as u64 + count as u64 * sizeof(ProcessStat) as u64) as ptr<ProcessStat>;
4020 (*stat).pid = (*curr).pid;
4021 (*stat).state = (*curr).state;
4022 (*stat).time_slice = (*curr).time_slice;
4023 (*stat).vram_usage = 0;
4024 count = count + 1;
4025 curr = (*curr).next;
4026 }
4027 return count;
4028 }
4029 let mut loopback_mac: MacAddr;
4030 let mut loopback_ip: Ipv4Addr;
4031 fn loopback_init() {
4032 for i in 0..6 { loopback_mac.addr[i] = 0; }
4033 loopback_ip.addr[0] = 127;
4034 loopback_ip.addr[1] = 0;
4035 loopback_ip.addr[2] = 0;
4036 loopback_ip.addr[3] = 1;
4037 }
4038 fn loopback_send(packet: ptr<u8>, length: u32) {
4039 let rx_buffer = pmm_alloc_blocks((length as u64 / PAGE_SIZE) + 1) as ptr<u8>;
4040 memcpy(rx_buffer, packet, length as u64);
4041 pmm_free_blocks(rx_buffer as u64, (length as u64 / PAGE_SIZE) + 1);
4042 }
4043 struct AegisContainer {
4044 container_id: u64,
4045 vfs_root: ptr<VfsNode>,
4046 pid_offset: u64,
4047 network_isolated: bool,
4048 virtual_ip: Ipv4Addr,
4049 memory_limit: u64,
4050 current_memory: u64,
4051 is_active: bool,
4052 name: [u8; 32],
4053 }
4054 let mut global_containers: [AegisContainer; 64];
4055 let mut container_count: u64 = 1;
4056 fn container_init() {
4057 for i in 0..64 {
4058 global_containers[i].is_active = false;
4059 }
4060 }
4061 fn container_create(name: ptr<u8>, mem_limit: u64) -> ptr<AegisContainer> {
4062 for i in 0..64 {
4063 if !global_containers[i].is_active {
4064 global_containers[i].container_id = container_count;
4065 container_count = container_count + 1;
4066 strcpy(&(global_containers[i].name[0]) as ptr<u8>, name);
4067 global_containers[i].memory_limit = mem_limit;
4068 global_containers[i].current_memory = 0;
4069 global_containers[i].pid_offset = container_count * 10000;
4070 global_containers[i].network_isolated = true;
4071
4072 let root_name = pmm_alloc_blocks(1) as ptr<u8>;
4073 strcpy(root_name, "c_root" as ptr<u8>);
4074 global_containers[i].vfs_root = vfs_create_node(global_vfs_root, root_name, 0x07);
4075 pmm_free_blocks(root_name as u64, 1);
4076
4077 global_containers[i].is_active = true;
4078 return &global_containers[i];
4079 }
4080 }
4081 return 0 as ptr<AegisContainer>;
4082 }
4083 fn container_execute(container: ptr<AegisContainer>, path: ptr<u8>) -> u64 {
4084 let node = vfs_find_child((*container).vfs_root, path);
4085 if node == 0 as ptr<VfsNode> { return 0; }
4086
4087 let pid = execve_ring3(path, 0, 0);
4088 if pid != 0 {
4089 let mut proc = process_queue;
4090 while proc != 0 as ptr<ProcessControlBlock> {
4091 if (*proc).pid == pid {
4092 (*proc).pid = (*container).pid_offset + pid;
4093 break;
4094 }
4095 proc = (*proc).next;
4096 }
4097 return (*container).pid_offset + pid;
4098 }
4099 return 0;
4100 }
4101 struct IntelGpuRing {
4102 tail: u32,
4103 head: u32,
4104 start: u32,
4105 ctl: u32,
4106 }
4107 let mut intel_mmio_base: u64 = 0;
4108 let mut intel_ring_buf: ptr<u32>;
4109 let mut intel_ring_tail: u32 = 0;
4110 fn intel_gpu_read(offset: u32) -> u32 {
4111 let ptr = (intel_mmio_base + offset as u64) as ptr<u32>;
4112 return *ptr;
4113 }
4114 fn intel_gpu_write(offset: u32, val: u32) {
4115 let ptr = (intel_mmio_base + offset as u64) as ptr<u32>;
4116 *ptr = val;
4117 }
4118 fn intel_gpu_init(bar0: u64) {
4119 intel_mmio_base = bar0 & 0xFFFFFFFFFFFFFFF0;
4120 intel_ring_buf = pmm_alloc_blocks(4) as ptr<u32>;
4121 memset(intel_ring_buf as ptr<u8>, 0, PAGE_SIZE * 4);
4122
4123 intel_gpu_write(0x02080, 0);
4124 intel_gpu_write(0x02030, 0);
4125 intel_gpu_write(0x02034, intel_ring_buf as u64 as u32);
4126 let ring_size = (PAGE_SIZE * 4) as u32;
4127 intel_gpu_write(0x02038, ((ring_size / 4096) - 1) | 1);
4128
4129 intel_ring_tail = 0;
4130 }
4131 fn intel_gpu_submit_cmd(cmd: u32) {
4132 *(intel_ring_buf as u64 + intel_ring_tail as u64 * 4) as ptr<u32> = cmd;
4133 intel_ring_tail = (intel_ring_tail + 1) % ((PAGE_SIZE as u32 * 4) / 4);
4134 let aligned_tail = (intel_ring_tail * 4) & 0x1FFFF8;
4135 intel_gpu_write(0x02030, aligned_tail);
4136 }
4137 fn intel_gpu_fill_rect(x: u32, y: u32, w: u32, h: u32, color: u32) {
4138 let cmd_len = 6;
4139 intel_gpu_submit_cmd(0x50000000 | (cmd_len - 2));
4140 intel_gpu_submit_cmd((y << 16) | x);
4141 intel_gpu_submit_cmd(((y + h) << 16) | (x + w));
4142 intel_gpu_submit_cmd(color);
4143 intel_gpu_submit_cmd(0);
4144 intel_gpu_submit_cmd(0);
4145 }
4146 const PCI_CAP_ID_MSI: u8 = 0x05;
4147 const PCI_CAP_ID_MSIX: u8 = 0x11;
4148 struct MsixTableEntry {
4149 msg_addr_lo: u32,
4150 msg_addr_hi: u32,
4151 msg_data: u32,
4152 vector_ctrl: u32,
4153 }
4154 fn pcie_find_capability(base: u64, bus: u8, dev: u8, func: u8, cap_id: u8) -> u8 {
4155 let status = pcie_read_16(base, bus, dev, func, 0x06);
4156 if (status & 0x0010) == 0 { return 0; }
4157
4158 let mut cap_ptr = pcie_read_16(base, bus, dev, func, 0x34) & 0xFC;
4159 while cap_ptr != 0 {
4160 let cap_data = pcie_read_16(base, bus, dev, func, cap_ptr);
4161 let id = (cap_data & 0xFF) as u8;
4162 let next = ((cap_data >> 8) & 0xFC) as u8;
4163 if id == cap_id { return cap_ptr as u8; }
4164 cap_ptr = next as u16;
4165 }
4166 return 0;
4167 }
4168 fn pcie_enable_msix(base: u64, bus: u8, dev: u8, func: u8, vector: u8, apic_id: u8) {
4169 let cap_offset = pcie_find_capability(base, bus, dev, func, PCI_CAP_ID_MSIX);
4170 if cap_offset == 0 { return; }
4171
4172 let msg_ctrl = pcie_read_16(base, bus, dev, func, cap_offset as u16 + 2);
4173 let table_offset_reg = pcie_read_32(base, bus, dev, func, cap_offset as u16 + 4);
4174 let bir = (table_offset_reg & 0x07) as u8;
4175 let table_offset = table_offset_reg & 0xFFFFFFF8;
4176
4177 let bar_reg = 0x10 + (bir * 4);
4178 let bar_val = pcie_read_32(base, bus, dev, func, bar_reg as u16);
4179 let bar_base = (bar_val & 0xFFFFFFF0) as u64;
4180
4181 let table_ptr = (bar_base + table_offset as u64) as ptr<MsixTableEntry>;
4182
4183 let addr_lo = 0xFEE00000 | ((apic_id as u32) << 12);
4184 let data = vector as u32;
4185
4186 (*table_ptr).msg_addr_lo = addr_lo;
4187 (*table_ptr).msg_addr_hi = 0;
4188 (*table_ptr).msg_data = data;
4189 (*table_ptr).vector_ctrl = 0;
4190
4191 pcie_write_32(base, bus, dev, func, cap_offset as u16 + 2, (msg_ctrl | 0x8000) as u32);
4192 }
4193 struct RiffHeader {
4194 chunk_id: u32,
4195 chunk_size: u32,
4196 format: u32,
4197 }
4198 struct WavFormatChunk {
4199 subchunk1_id: u32,
4200 subchunk1_size: u32,
4201 audio_format: u16,
4202 num_channels: u16,
4203 sample_rate: u32,
4204 byte_rate: u32,
4205 block_align: u16,
4206 bits_per_sample: u16,
4207 }
4208 struct WavDataChunk {
4209 subchunk2_id: u32,
4210 subchunk2_size: u32,
4211 }
4212 fn audio_play_wav(wav_data: ptr<u8>) {
4213 let riff = wav_data as ptr<RiffHeader>;
4214 if (*riff).chunk_id != 0x46464952 { return; } // 'RIFF'
4215 if (*riff).format != 0x45564157 { return; } // 'WAVE'
4216
4217 let fmt = (wav_data as u64 + sizeof(RiffHeader) as u64) as ptr<WavFormatChunk>;
4218 if (*fmt).subchunk1_id != 0x20746d66 { return; } // 'fmt '
4219
4220 let data_offset = sizeof(RiffHeader) as u64 + 8 + (*fmt).subchunk1_size as u64;
4221 let data_chunk = (wav_data as u64 + data_offset) as ptr<WavDataChunk>;
4222 if (*data_chunk).subchunk2_id != 0x61746164 { return; } // 'data'
4223
4224 let pcm_data = (wav_data as u64 + data_offset + 8) as ptr<u8>;
4225 let pcm_size = (*data_chunk).subchunk2_size;
4226
4227 mixer_play_pcm(pcm_data, pcm_size / 4, (*fmt).sample_rate);
4228 }
4229 struct NatEntry {
4230 internal_ip: Ipv4Addr,
4231 internal_port: u16,
4232 external_port: u16,
4233 protocol: u8,
4234 is_active: bool,
4235 }
4236 let mut global_nat_table: [NatEntry; 1024];
4237 let mut nat_next_port: u16 = 50000;
4238 fn nat_init() {
4239 for i in 0..1024 {
4240 global_nat_table[i].is_active = false;
4241 }
4242 }
4243 fn nat_add_mapping(int_ip: Ipv4Addr, int_port: u16, proto: u8) -> u16 {
4244 for i in 0..1024 {
4245 if !global_nat_table[i].is_active {
4246 global_nat_table[i].internal_ip = int_ip;
4247 global_nat_table[i].internal_port = int_port;
4248 global_nat_table[i].external_port = nat_next_port;
4249 global_nat_table[i].protocol = proto;
4250 global_nat_table[i].is_active = true;
4251
4252 let port = nat_next_port;
4253 nat_next_port = nat_next_port + 1;
4254 if nat_next_port > 65000 { nat_next_port = 50000; }
4255 return port;
4256 }
4257 }
4258 return 0;
4259 }
4260 fn nat_translate_outbound(packet: ptr<u8>) {
4261 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
4262 let proto = (*iph).protocol;
4263
4264 if proto == 6 {
4265 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
4266 let ext_port = nat_add_mapping((*iph).src_ip, htons((*tcph).src_port), proto);
4267
4268 for i in 0..4 { (*iph).src_ip.addr[i] = system_ip.addr[i]; }
4269 (*tcph).src_port = htons(ext_port);
4270 (*tcph).checksum = 0;
4271 (*iph).checksum = 0;
4272 }
4273 }
4274 fn nat_translate_inbound(packet: ptr<u8>) -> bool {
4275 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
4276 let proto = (*iph).protocol;
4277
4278 if proto == 6 {
4279 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
4280 let dest_port = htons((*tcph).dest_port);
4281
4282 for i in 0..1024 {
4283 if global_nat_table[i].is_active && global_nat_table[i].external_port == dest_port && global_nat_table[i].protocol == proto {
4284 for j in 0..4 { (*iph).dest_ip.addr[j] = global_nat_table[i].internal_ip.addr[j]; }
4285 (*tcph).dest_port = htons(global_nat_table[i].internal_port);
4286 return true;
4287 }
4288 }
4289 }
4290 return false;
4291 }
4292 struct AhciCmdFis {
4293 fis_type: u8,
4294 pmport_c: u8,
4295 command: u8,
4296 feature_l: u8,
4297 lba0: u8,
4298 lba1: u8,
4299 lba2: u8,
4300 device: u8,
4301 lba3: u8,
4302 lba4: u8,
4303 lba5: u8,
4304 feature_h: u8,
4305 count_l: u8,
4306 count_h: u8,
4307 icc: u8,
4308 control: u8,
4309 rsv1: [u8; 4],
4310 }
4311 fn ahci_find_cmd_slot(port: ptr<AHCIPortRegs>) -> i32 {
4312 let slots = ((*global_ahci_hba).cap >> 8) & 0x1F;
4313 for i in 0..=slots {
4314 if ((*port).ci & (1 << i)) == 0 && ((*port).sact & (1 << i)) == 0 {
4315 return i as i32;
4316 }
4317 }
4318 return -1;
4319 }
4320 fn ahci_read_sectors(port: ptr<AHCIPortRegs>, start_lba: u64, count: u32, buf_phys: u64) -> bool {
4321 (*port).is = 0xFFFFFFFF;
4322 let slot = ahci_find_cmd_slot(port);
4323 if slot == -1 { return false; }
4324
4325 let cmd_header = ((*port).clb + (slot as u64 * sizeof(AHCICmdHeader) as u64)) as ptr<AHCICmdHeader>;
4326 (*cmd_header).cfl_p_r_c = (sizeof(AhciCmdFis) / 4) as u16;
4327 (*cmd_header).prdtl = 1;
4328
4329 let cmd_table = (*cmd_header).ctba as ptr<AHCICmdTable>;
4330 memset(cmd_table as ptr<u8>, 0, sizeof(AHCICmdTable) as u64);
4331
4332 (*cmd_table).prdt_entry[0].dba = buf_phys;
4333 (*cmd_table).prdt_entry[0].dbc_i = (count * 512) - 1;
4334
4335 let fis = &(*cmd_table).cfis[0] as ptr<AhciCmdFis>;
4336 (*fis).fis_type = 0x27;
4337 (*fis).pmport_c = 0x80;
4338 (*fis).command = 0x25;
4339
4340 (*fis).lba0 = (start_lba & 0xFF) as u8;
4341 (*fis).lba1 = ((start_lba >> 8) & 0xFF) as u8;
4342 (*fis).lba2 = ((start_lba >> 16) & 0xFF) as u8;
4343 (*fis).device = 0x40;
4344
4345 (*fis).lba3 = ((start_lba >> 24) & 0xFF) as u8;
4346 (*fis).lba4 = ((start_lba >> 32) & 0xFF) as u8;
4347 (*fis).lba5 = ((start_lba >> 40) & 0xFF) as u8;
4348
4349 (*fis).count_l = (count & 0xFF) as u8;
4350 (*fis).count_h = ((count >> 8) & 0xFF) as u8;
4351
4352 while ((*port).tfd & (0x80 | 0x08)) != 0 { cpu_pause(); }
4353 (*port).ci = 1 << slot;
4354
4355 while true {
4356 if ((*port).ci & (1 << slot)) == 0 { break; }
4357 if ((*port).is & 0x40000000) != 0 { return false; }
4358 cpu_pause();
4359 }
4360 return true;
4361 }
4362 fn ahci_write_sectors(port: ptr<AHCIPortRegs>, start_lba: u64, count: u32, buf_phys: u64) -> bool {
4363 (*port).is = 0xFFFFFFFF;
4364 let slot = ahci_find_cmd_slot(port);
4365 if slot == -1 { return false; }
4366
4367 let cmd_header = ((*port).clb + (slot as u64 * sizeof(AHCICmdHeader) as u64)) as ptr<AHCICmdHeader>;
4368 (*cmd_header).cfl_p_r_c = ((sizeof(AhciCmdFis) / 4) as u16) | 0x0040;
4369 (*cmd_header).prdtl = 1;
4370
4371 let cmd_table = (*cmd_header).ctba as ptr<AHCICmdTable>;
4372 memset(cmd_table as ptr<u8>, 0, sizeof(AHCICmdTable) as u64);
4373
4374 (*cmd_table).prdt_entry[0].dba = buf_phys;
4375 (*cmd_table).prdt_entry[0].dbc_i = (count * 512) - 1;
4376
4377 let fis = &(*cmd_table).cfis[0] as ptr<AhciCmdFis>;
4378 (*fis).fis_type = 0x27;
4379 (*fis).pmport_c = 0x80;
4380 (*fis).command = 0x35;
4381
4382 (*fis).lba0 = (start_lba & 0xFF) as u8;
4383 (*fis).lba1 = ((start_lba >> 8) & 0xFF) as u8;
4384 (*fis).lba2 = ((start_lba >> 16) & 0xFF) as u8;
4385 (*fis).device = 0x40;
4386
4387 (*fis).lba3 = ((start_lba >> 24) & 0xFF) as u8;
4388 (*fis).lba4 = ((start_lba >> 32) & 0xFF) as u8;
4389 (*fis).lba5 = ((start_lba >> 40) & 0xFF) as u8;
4390
4391 (*fis).count_l = (count & 0xFF) as u8;
4392 (*fis).count_h = ((count >> 8) & 0xFF) as u8;
4393
4394 while ((*port).tfd & (0x80 | 0x08)) != 0 { cpu_pause(); }
4395 (*port).ci = 1 << slot;
4396
4397 while true {
4398 if ((*port).ci & (1 << slot)) == 0 { break; }
4399 if ((*port).is & 0x40000000) != 0 { return false; }
4400 cpu_pause();
4401 }
4402 return true;
4403 }
4404 struct SignalContext {
4405 pending_mask: u32,
4406 blocked_mask: u32,
4407 handlers: [u64; 32],
4408 trampoline_addr: u64,
4409 saved_ctx: CpuContext,
4410 is_handling: bool,
4411 }
4412 struct ProcessControlBlockExt {
4413 base: ProcessControlBlock,
4414 sig_ctx: ptr<SignalContext>,
4415 }
4416 const SIGKILL: u32 = 9;
4417 const SIGSEGV: u32 = 11;
4418 const SIGTERM: u32 = 15;
4419 fn signal_init_process(proc: ptr<ProcessControlBlock>) {
4420 let proc_ext = proc as ptr<ProcessControlBlockExt>;
4421 (*proc_ext).sig_ctx = pmm_alloc_blocks(1) as ptr<SignalContext>;
4422 memset((*proc_ext).sig_ctx as ptr<u8>, 0, sizeof(SignalContext) as u64);
4423 }
4424 fn signal_send(target_pid: u64, signum: u32) -> bool {
4425 let mut curr = process_queue;
4426 while curr != 0 as ptr<ProcessControlBlock> {
4427 if (*curr).pid == target_pid {
4428 let proc_ext = curr as ptr<ProcessControlBlockExt>;
4429 if (*(*proc_ext).sig_ctx).is_handling { return false; }
4430 (*(*proc_ext).sig_ctx).pending_mask |= 1 << signum;
4431 if signum == SIGKILL {
4432 (*curr).state = 0;
4433 }
4434 return true;
4435 }
4436 curr = (*curr).next;
4437 }
4438 return false;
4439 }
4440 fn signal_check_pending() {
4441 if current_process == 0 as ptr<ProcessControlBlock> { return; }
4442 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
4443 let sig_ctx = (*proc_ext).sig_ctx;
4444
4445 if (*sig_ctx).is_handling { return; }
4446
4447 let active_sigs = (*sig_ctx).pending_mask & !(*sig_ctx).blocked_mask;
4448 if active_sigs == 0 { return; }
4449
4450 for i in 1..32 {
4451 if (active_sigs & (1 << i)) != 0 {
4452 (*sig_ctx).pending_mask &= !(1 << i);
4453 let handler = (*sig_ctx).handlers[i as usize];
4454 if handler != 0 {
4455 memcpy(&((*sig_ctx).saved_ctx) as ptr<u8>, (*current_process).context as ptr<u8>, sizeof(CpuContext) as u64);
4456 (*sig_ctx).is_handling = true;
4457 (*(*current_process).context).rip = handler;
4458 (*(*current_process).context).rdi = i as u64;
4459 let rsp = (*(*current_process).context).rsp;
4460 (*(*current_process).context).rsp = rsp - 128;
4461 return;
4462 }
4463 }
4464 }
4465 }
4466 fn signal_return() {
4467 if current_process == 0 as ptr<ProcessControlBlock> { return; }
4468 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
4469 let sig_ctx = (*proc_ext).sig_ctx;
4470 if !(*sig_ctx).is_handling { return; }
4471
4472 memcpy((*current_process).context as ptr<u8>, &((*sig_ctx).saved_ctx) as ptr<u8>, sizeof(CpuContext) as u64);
4473 (*sig_ctx).is_handling = false;
4474 }
4475 struct TcpCongestionExt {
4476 cwnd: u32,
4477 ssthresh: u32,
4478 dup_acks: u32,
4479 rtt: u32,
4480 rto: u32,
4481 in_fast_recovery: bool,
4482 }
4483 let mut global_tcp_cc: [TcpCongestionExt; 1024];
4484 fn tcp_cc_init(sock_idx: u32) {
4485 global_tcp_cc[sock_idx as usize].cwnd = 1460;
4486 global_tcp_cc[sock_idx as usize].ssthresh = 65535;
4487 global_tcp_cc[sock_idx as usize].dup_acks = 0;
4488 global_tcp_cc[sock_idx as usize].rto = 1000;
4489 global_tcp_cc[sock_idx as usize].in_fast_recovery = false;
4490 }
4491 fn tcp_cc_ack_received(sock_idx: u32, ack_diff: u32, is_dup: bool) {
4492 let cc = &global_tcp_cc[sock_idx as usize];
4493 if is_dup {
4494 (*cc).dup_acks = (*cc).dup_acks + 1;
4495 if (*cc).dup_acks == 3 {
4496 (*cc).ssthresh = (*cc).cwnd / 2;
4497 if (*cc).ssthresh < 1460 * 2 { (*cc).ssthresh = 1460 * 2; }
4498 (*cc).cwnd = (*cc).ssthresh + 3 * 1460;
4499 (*cc).in_fast_recovery = true;
4500 } else if (*cc).in_fast_recovery {
4501 (*cc).cwnd = (*cc).cwnd + 1460;
4502 }
4503 } else {
4504 (*cc).dup_acks = 0;
4505 if (*cc).in_fast_recovery {
4506 (*cc).cwnd = (*cc).ssthresh;
4507 (*cc).in_fast_recovery = false;
4508 } else {
4509 if (*cc).cwnd < (*cc).ssthresh {
4510 (*cc).cwnd = (*cc).cwnd + 1460;
4511 } else {
4512 (*cc).cwnd = (*cc).cwnd + (1460 * 1460) / (*cc).cwnd;
4513 }
4514 }
4515 }
4516 }
4517 fn tcp_cc_timeout(sock_idx: u32) {
4518 let cc = &global_tcp_cc[sock_idx as usize];
4519 (*cc).ssthresh = (*cc).cwnd / 2;
4520 if (*cc).ssthresh < 1460 * 2 { (*cc).ssthresh = 1460 * 2; }
4521 (*cc).cwnd = 1460;
4522 (*cc).dup_acks = 0;
4523 (*cc).in_fast_recovery = false;
4524 (*cc).rto = (*cc).rto * 2;
4525 if (*cc).rto > 64000 { (*cc).rto = 64000; }
4526 }
4527 struct VirtualConsole {
4528 id: u32,
4529 buffer_phys: u64,
4530 cursor_x: u32,
4531 cursor_y: u32,
4532 fg_color: u32,
4533 bg_color: u32,
4534 is_active: bool,
4535 }
4536 let mut global_vt_list: [VirtualConsole; 6];
4537 let mut vt_active_id: u32 = 0;
4538 let mut vt_lock: Spinlock;
4539 fn vt_init() {
4540 spin_init(&vt_lock);
4541 for i in 0..6 {
4542 global_vt_list[i].id = i as u32;
4543 global_vt_list[i].buffer_phys = pmm_alloc_blocks((comp_width * comp_height * 4) / PAGE_SIZE as u32 + 1);
4544 memset(global_vt_list[i].buffer_phys as ptr<u8>, 0, (comp_width * comp_height * 4) as u64);
4545 global_vt_list[i].cursor_x = 0;
4546 global_vt_list[i].cursor_y = 0;
4547 global_vt_list[i].fg_color = 0xFFFFFF;
4548 global_vt_list[i].bg_color = 0x000000;
4549 global_vt_list[i].is_active = false;
4550 }
4551 global_vt_list[0].is_active = true;
4552 }
4553 fn vt_switch(new_id: u32) {
4554 if new_id >= 6 || new_id == vt_active_id { return; }
4555 spin_lock(&vt_lock);
4556 global_vt_list[vt_active_id as usize].is_active = false;
4557 vt_active_id = new_id;
4558 global_vt_list[vt_active_id as usize].is_active = true;
4559 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);
4560 spin_unlock(&vt_lock);
4561 }
4562 fn vt_write_char(vt_id: u32, c: u8) {
4563 let vt = &global_vt_list[vt_id as usize];
4564 if c == 10 {
4565 (*vt).cursor_x = 0;
4566 (*vt).cursor_y = (*vt).cursor_y + system_font_h;
4567 } else {
4568 let buf = (*vt).buffer_phys as ptr<u32>;
4569 let glyph_offset = c as u64 * system_font_h as u64;
4570 let glyph = (system_font_ptr as u64 + glyph_offset) as ptr<u8>;
4571
4572 for cy in 0..system_font_h {
4573 let row = *(glyph + cy as u64);
4574 for cx in 0..system_font_w {
4575 let px = (*vt).cursor_x + cx;
4576 let py = (*vt).cursor_y + cy;
4577 if px < comp_width && py < comp_height {
4578 let p_idx = (py * comp_width + px) as u64;
4579 if (row & (0x80 >> cx)) != 0 {
4580 *(buf + p_idx) = (*vt).fg_color;
4581 } else {
4582 *(buf + p_idx) = (*vt).bg_color;
4583 }
4584 }
4585 }
4586 }
4587 (*vt).cursor_x = (*vt).cursor_x + system_font_w;
4588 if (*vt).cursor_x >= comp_width {
4589 (*vt).cursor_x = 0;
4590 (*vt).cursor_y = (*vt).cursor_y + system_font_h;
4591 }
4592 }
4593
4594 if (*vt).cursor_y >= comp_height {
4595 let buf = (*vt).buffer_phys as ptr<u32>;
4596 let row_bytes = (comp_width * system_font_h * 4) as u64;
4597 let total_bytes = (comp_width * comp_height * 4) as u64;
4598 memmove(buf as ptr<u8>, (buf as u64 + row_bytes) as ptr<u8>, total_bytes - row_bytes);
4599 memset((buf as u64 + total_bytes - row_bytes) as ptr<u8>, 0, row_bytes);
4600 (*vt).cursor_y = (*vt).cursor_y - system_font_h;
4601 }
4602
4603 if (*vt).is_active {
4604 memcpy(fb_ptr as ptr<u8>, (*vt).buffer_phys as ptr<u8>, (comp_width * comp_height * 4) as u64);
4605 }
4606 }
4607 struct AmlNode {
4608 opcode: u8,
4609 name: [u8; 4],
4610 length: u32,
4611 data_ptr: ptr<u8>,
4612 parent: ptr<AmlNode>,
4613 child: ptr<AmlNode>,
4614 next: ptr<AmlNode>,
4615 }
4616 let mut aml_root: ptr<AmlNode>;
4617 fn aml_parse_name(data: ptr<u8>) -> u32 {
4618 let mut offset: u32 = 0;
4619 if *data == 0x5C { offset = offset + 1; }
4620 if *(data as u64 + offset as u64) as ptr<u8> == 0x2E { offset = offset + 1; }
4621 offset = offset + 4;
4622 return offset;
4623 }
4624 fn aml_parse_pkg_length(data: ptr<u8>) -> (u32, u32) {
4625 let lead = *data;
4626 let byte_count = (lead >> 6) as u32;
4627 if byte_count == 0 {
4628 return ((lead & 0x3F) as u32, 1);
4629 }
4630 let mut length = (lead & 0x0F) as u32;
4631 for i in 0..byte_count {
4632 length |= (*(data as u64 + 1 + i as u64) as u32) << (4 + i * 8);
4633 }
4634 return (length, byte_count + 1);
4635 }
4636 fn aml_process_scope(parent: ptr<AmlNode>, data: ptr<u8>, limit: u32) {
4637 let mut offset: u32 = 0;
4638 while offset < limit {
4639 let opcode = *(data as u64 + offset as u64) as ptr<u8>;
4640 let mut parsed_len: u32 = 1;
4641
4642 if opcode == 0x10 {
4643 let (pkg_len, pkg_bytes) = aml_parse_pkg_length((data as u64 + offset as u64 + 1) as ptr<u8>);
4644 let name_offset = aml_parse_name((data as u64 + offset as u64 + 1 + pkg_bytes as u64) as ptr<u8>);
4645 parsed_len = 1 + pkg_bytes + pkg_len;
4646
4647 let node = pmm_alloc_blocks(1) as ptr<AmlNode>;
4648 memset(node as ptr<u8>, 0, sizeof(AmlNode) as u64);
4649 (*node).opcode = opcode;
4650 (*node).parent = parent;
4651
4652 if (*parent).child == 0 as ptr<AmlNode> {
4653 (*parent).child = node;
4654 } else {
4655 let mut curr = (*parent).child;
4656 while (*curr).next != 0 as ptr<AmlNode> { curr = (*curr).next; }
4657 (*curr).next = node;
4658 }
4659
4660 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);
4661 } else if opcode == 0x14 {
4662 let (pkg_len, pkg_bytes) = aml_parse_pkg_length((data as u64 + offset as u64 + 1) as ptr<u8>);
4663 parsed_len = 1 + pkg_bytes + pkg_len;
4664 } else if opcode == 0x08 {
4665 let name_offset = aml_parse_name((data as u64 + offset as u64 + 1) as ptr<u8>);
4666 parsed_len = 1 + name_offset + 1;
4667 } else {
4668 parsed_len = 1;
4669 }
4670 offset = offset + parsed_len;
4671 }
4672 }
4673 fn acpi_dsdt_init() {
4674 if acpi_fadt == 0 as ptr<FADTHeader> { return; }
4675 let dsdt_ptr = (*acpi_fadt).dsdt as u64 as ptr<ACPISDTHeader>;
4676 if !acpi_checksum(dsdt_ptr as ptr<u8>, (*dsdt_ptr).length) { return; }
4677
4678 aml_root = pmm_alloc_blocks(1) as ptr<AmlNode>;
4679 memset(aml_root as ptr<u8>, 0, sizeof(AmlNode) as u64);
4680
4681 let aml_data = (dsdt_ptr as u64 + sizeof(ACPISDTHeader) as u64) as ptr<u8>;
4682 let aml_len = (*dsdt_ptr).length - sizeof(ACPISDTHeader) as u32;
4683 aml_process_scope(aml_root, aml_data, aml_len);
4684 }
4685 const DOM_NODE_ELEMENT: u8 = 1;
4686 const DOM_NODE_TEXT: u8 = 2;
4687 struct HtmlAttribute {
4688 name: [u8; 32],
4689 value: [u8; 128],
4690 next: ptr<HtmlAttribute>,
4691 }
4692 struct DomNode {
4693 node_type: u8,
4694 tag_name: [u8; 32],
4695 text_content: ptr<u8>,
4696 attributes: ptr<HtmlAttribute>,
4697 parent: ptr<DomNode>,
4698 first_child: ptr<DomNode>,
4699 next_sibling: ptr<DomNode>,
4700 }
4701 let mut dom_node_pool: ptr<DomNode>;
4702 let mut dom_pool_idx: u32 = 0;
4703 fn html_init_parser() {
4704 dom_node_pool = pmm_alloc_blocks(64) as ptr<DomNode>;
4705 memset(dom_node_pool as ptr<u8>, 0, PAGE_SIZE * 64);
4706 dom_pool_idx = 0;
4707 }
4708 fn html_alloc_node() -> ptr<DomNode> {
4709 let node = (dom_node_pool as u64 + dom_pool_idx as u64 * sizeof(DomNode) as u64) as ptr<DomNode>;
4710 dom_pool_idx = dom_pool_idx + 1;
4711 return node;
4712 }
4713 fn html_skip_whitespace(html: ptr<u8>, pos: ptr<u32>) {
4714 while *(html as u64 + *pos as u64) as ptr<u8> == ' ' as u8 ||
4715 *(html as u64 + *pos as u64) as ptr<u8> == 10 ||
4716 *(html as u64 + *pos as u64) as ptr<u8> == 9 ||
4717 *(html as u64 + *pos as u64) as ptr<u8> == 13 {
4718 *pos = *pos + 1;
4719 }
4720 }
4721 fn html_parse_tag_name(html: ptr<u8>, pos: ptr<u32>, out_name: ptr<u8>) {
4722 let mut i: u32 = 0;
4723 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 &&
4724 *(html as u64 + *pos as u64) as ptr<u8> != ' ' as u8 &&
4725 *(html as u64 + *pos as u64) as ptr<u8> != '/' as u8 &&
4726 *(html as u64 + *pos as u64) as ptr<u8> != 0 &&
4727 i < 31 {
4728 *(out_name as u64 + i as u64) as ptr<u8> = *(html as u64 + *pos as u64) as ptr<u8>;
4729 *pos = *pos + 1;
4730 i = i + 1;
4731 }
4732 *(out_name as u64 + i as u64) as ptr<u8> = 0;
4733 }
4734 fn html_parse_node(html: ptr<u8>, pos: ptr<u32>, parent: ptr<DomNode>) -> ptr<DomNode> {
4735 html_skip_whitespace(html, pos);
4736 if *(html as u64 + *pos as u64) as ptr<u8> == 0 { return 0 as ptr<DomNode>; }
4737
4738 let node = html_alloc_node();
4739 (*node).parent = parent;
4740
4741 if *(html as u64 + *pos as u64) as ptr<u8> == '<' as u8 {
4742 *pos = *pos + 1;
4743 if *(html as u64 + *pos as u64) as ptr<u8> == '/' as u8 {
4744 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
4745 *pos = *pos + 1;
4746 }
4747 if *(html as u64 + *pos as u64) as ptr<u8> == '>' as u8 { *pos = *pos + 1; }
4748 return 0 as ptr<DomNode>;
4749 }
4750
4751 (*node).node_type = DOM_NODE_ELEMENT;
4752 html_parse_tag_name(html, pos, &((*node).tag_name[0]) as ptr<u8>);
4753
4754 while *(html as u64 + *pos as u64) as ptr<u8> != '>' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
4755 *pos = *pos + 1;
4756 }
4757
4758 let mut is_self_closing = false;
4759 if *(html as u64 + *pos as u64 - 1) as ptr<u8> == '/' as u8 {
4760 is_self_closing = true;
4761 }
4762
4763 if *(html as u64 + *pos as u64) as ptr<u8> == '>' as u8 { *pos = *pos + 1; }
4764
4765 if !is_self_closing {
4766 let mut last_child = 0 as ptr<DomNode>;
4767 loop {
4768 let child = html_parse_node(html, pos, node);
4769 if child == 0 as ptr<DomNode> { break; }
4770 if (*node).first_child == 0 as ptr<DomNode> {
4771 (*node).first_child = child;
4772 } else {
4773 (*last_child).next_sibling = child;
4774 }
4775 last_child = child;
4776 }
4777 }
4778 } else {
4779 (*node).node_type = DOM_NODE_TEXT;
4780 let mut start_pos = *pos;
4781 let mut len: u32 = 0;
4782 while *(html as u64 + *pos as u64) as ptr<u8> != '<' as u8 && *(html as u64 + *pos as u64) as ptr<u8> != 0 {
4783 *pos = *pos + 1;
4784 len = len + 1;
4785 }
4786 (*node).text_content = pmm_alloc_blocks((len / PAGE_SIZE as u32) + 1) as ptr<u8>;
4787 memcpy((*node).text_content, (html as u64 + start_pos as u64) as ptr<u8>, len as u64);
4788 *((*node).text_content as u64 + len as u64) as ptr<u8> = 0;
4789 }
4790
4791 return node;
4792 }
4793 const RAID_LEVEL_5: u32 = 5;
4794 const RAID_STRIPE_SIZE: u64 = 65536;
4795 struct RaidDisk {
4796 disk_id: u32,
4797 ahci_port: ptr<AHCIPortRegs>,
4798 is_online: bool,
4799 total_sectors: u64,
4800 }
4801 struct RaidArray {
4802 array_id: u32,
4803 level: u32,
4804 disks: [RaidDisk; 8],
4805 disk_count: u32,
4806 online_count: u32,
4807 total_capacity: u64,
4808 stripe_size: u64,
4809 }
4810 let mut global_raid_sys: RaidArray;
4811 fn raid_init_system() {
4812 global_raid_sys.array_id = 1;
4813 global_raid_sys.level = RAID_LEVEL_5;
4814 global_raid_sys.disk_count = 0;
4815 global_raid_sys.online_count = 0;
4816 global_raid_sys.stripe_size = RAID_STRIPE_SIZE;
4817 }
4818 fn raid_add_disk(port: ptr<AHCIPortRegs>, sectors: u64) {
4819 if global_raid_sys.disk_count < 8 {
4820 let idx = global_raid_sys.disk_count;
4821 global_raid_sys.disks[idx as usize].disk_id = idx;
4822 global_raid_sys.disks[idx as usize].ahci_port = port;
4823 global_raid_sys.disks[idx as usize].is_online = true;
4824 global_raid_sys.disks[idx as usize].total_sectors = sectors;
4825 global_raid_sys.disk_count = global_raid_sys.disk_count + 1;
4826 global_raid_sys.online_count = global_raid_sys.online_count + 1;
4827 global_raid_sys.total_capacity = (global_raid_sys.disk_count - 1) as u64 * sectors * 512;
4828 }
4829 }
4830 fn raid_compute_parity(buffers: ptr<u64>, count: u32, parity_buf: u64, size: u64) {
4831 let p_ptr = parity_buf as ptr<u64>;
4832 for i in 0..(size / 8) {
4833 let mut xor_val: u64 = 0;
4834 for d in 0..count {
4835 let buf_ptr = *(buffers + d as u64) as ptr<u64>;
4836 xor_val = xor_val ^ *(buf_ptr as u64 + i as u64 * 8) as ptr<u64>;
4837 }
4838 *(p_ptr as u64 + i as u64 * 8) as ptr<u64> = xor_val;
4839 }
4840 }
4841 fn raid_reconstruct_data(buffers: ptr<u64>, count: u32, parity_buf: u64, missing_idx: u32, size: u64) {
4842 let missing_ptr = *(buffers + missing_idx as u64) as ptr<u64>;
4843 let p_ptr = parity_buf as ptr<u64>;
4844 for i in 0..(size / 8) {
4845 let mut xor_val: u64 = *(p_ptr as u64 + i as u64 * 8) as ptr<u64>;
4846 for d in 0..count {
4847 if d != missing_idx {
4848 let buf_ptr = *(buffers + d as u64) as ptr<u64>;
4849 xor_val = xor_val ^ *(buf_ptr as u64 + i as u64 * 8) as ptr<u64>;
4850 }
4851 }
4852 *(missing_ptr as u64 + i as u64 * 8) as ptr<u64> = xor_val;
4853 }
4854 }
4855 fn raid_write_stripe(stripe_lba: u64, data_buffers: ptr<u64>) {
4856 let disk_cnt = global_raid_sys.disk_count;
4857 let parity_disk = (stripe_lba / (RAID_STRIPE_SIZE / 512)) % disk_cnt as u64;
4858
4859 let parity_buf = pmm_alloc_blocks(RAID_STRIPE_SIZE / PAGE_SIZE);
4860 raid_compute_parity(data_buffers, disk_cnt - 1, parity_buf, RAID_STRIPE_SIZE);
4861
4862 let mut data_idx = 0;
4863 for i in 0..disk_cnt {
4864 let port = global_raid_sys.disks[i as usize].ahci_port;
4865 if i as u64 == parity_disk {
4866 ahci_write_sectors(port, stripe_lba, (RAID_STRIPE_SIZE / 512) as u32, parity_buf);
4867 } else {
4868 let d_buf = *(data_buffers + data_idx as u64);
4869 ahci_write_sectors(port, stripe_lba, (RAID_STRIPE_SIZE / 512) as u32, d_buf);
4870 data_idx = data_idx + 1;
4871 }
4872 }
4873 pmm_free_blocks(parity_buf, RAID_STRIPE_SIZE / PAGE_SIZE);
4874 }
4875 struct CpuRunQueue {
4876 core_id: u32,
4877 head: ptr<ProcessControlBlock>,
4878 tail: ptr<ProcessControlBlock>,
4879 load_factor: u32,
4880 lock: Spinlock,
4881 }
4882 let mut global_run_queues: [CpuRunQueue; 256];
4883 fn smp_balancer_init() {
4884 for i in 0..smp_core_count {
4885 global_run_queues[i as usize].core_id = smp_cores[i as usize].apic_id as u32;
4886 global_run_queues[i as usize].head = 0 as ptr<ProcessControlBlock>;
4887 global_run_queues[i as usize].tail = 0 as ptr<ProcessControlBlock>;
4888 global_run_queues[i as usize].load_factor = 0;
4889 spin_init(&(global_run_queues[i as usize].lock));
4890 }
4891 }
4892 fn smp_enqueue_task(core_idx: u32, task: ptr<ProcessControlBlock>) {
4893 let rq = &global_run_queues[core_idx as usize];
4894 spin_lock(&((*rq).lock));
4895 (*task).next = 0 as ptr<ProcessControlBlock>;
4896 if (*rq).tail == 0 as ptr<ProcessControlBlock> {
4897 (*rq).head = task;
4898 (*rq).tail = task;
4899 } else {
4900 (*((*rq).tail)).next = task;
4901 (*rq).tail = task;
4902 }
4903 (*rq).load_factor = (*rq).load_factor + 1;
4904 spin_unlock(&((*rq).lock));
4905 }
4906 fn smp_dequeue_task(core_idx: u32) -> ptr<ProcessControlBlock> {
4907 let rq = &global_run_queues[core_idx as usize];
4908 spin_lock(&((*rq).lock));
4909 if (*rq).head == 0 as ptr<ProcessControlBlock> {
4910 spin_unlock(&((*rq).lock));
4911 return 0 as ptr<ProcessControlBlock>;
4912 }
4913 let task = (*rq).head;
4914 (*rq).head = (*task).next;
4915 if (*rq).head == 0 as ptr<ProcessControlBlock> {
4916 (*rq).tail = 0 as ptr<ProcessControlBlock>;
4917 }
4918 (*rq).load_factor = (*rq).load_factor - 1;
4919 spin_unlock(&((*rq).lock));
4920 return task;
4921 }
4922 fn smp_balance_load() {
4923 let mut max_load: u32 = 0;
4924 let mut min_load: u32 = 0xFFFFFFFF;
4925 let mut busiest_core: u32 = 0;
4926 let mut idlest_core: u32 = 0;
4927
4928 for i in 0..smp_core_count {
4929 let load = global_run_queues[i as usize].load_factor;
4930 if load > max_load { max_load = load; busiest_core = i; }
4931 if load < min_load { min_load = load; idlest_core = i; }
4932 }
4933
4934 if max_load > min_load + 2 {
4935 let task = smp_dequeue_task(busiest_core);
4936 if task != 0 as ptr<ProcessControlBlock> {
4937 smp_enqueue_task(idlest_core, task);
4938 }
4939 }
4940 }
4941 struct WaylandBuffer {
4942 shm_id: u64,
4943 width: u32,
4944 height: u32,
4945 stride: u32,
4946 format: u32,
4947 }
4948 struct WaylandSurface {
4949 surface_id: u32,
4950 owner_pid: u64,
4951 buffer: ptr<WaylandBuffer>,
4952 x: i32,
4953 y: i32,
4954 z_order: u32,
4955 is_mapped: bool,
4956 next: ptr<WaylandSurface>,
4957 }
4958 let mut display_srv_surfaces: ptr<WaylandSurface>;
4959 let mut display_srv_next_id: u32 = 1000;
4960 fn display_srv_create_surface(pid: u64) -> u32 {
4961 let surf = pmm_alloc_blocks(1) as ptr<WaylandSurface>;
4962 memset(surf as ptr<u8>, 0, sizeof(WaylandSurface) as u64);
4963 (*surf).surface_id = display_srv_next_id;
4964 display_srv_next_id = display_srv_next_id + 1;
4965 (*surf).owner_pid = pid;
4966 (*surf).is_mapped = false;
4967 (*surf).next = display_srv_surfaces;
4968 display_srv_surfaces = surf;
4969 return (*surf).surface_id;
4970 }
4971 fn display_srv_attach_buffer(surface_id: u32, shm_id: u64, w: u32, h: u32) {
4972 let mut curr = display_srv_surfaces;
4973 while curr != 0 as ptr<WaylandSurface> {
4974 if (*curr).surface_id == surface_id {
4975 let buf = pmm_alloc_blocks(1) as ptr<WaylandBuffer>;
4976 (*buf).shm_id = shm_id;
4977 (*buf).width = w;
4978 (*buf).height = h;
4979 (*buf).stride = w * 4;
4980 (*buf).format = 1;
4981 (*curr).buffer = buf;
4982 return;
4983 }
4984 curr = (*curr).next;
4985 }
4986 }
4987 fn display_srv_commit(surface_id: u32, x: i32, y: i32) {
4988 let mut curr = display_srv_surfaces;
4989 while curr != 0 as ptr<WaylandSurface> {
4990 if (*curr).surface_id == surface_id {
4991 (*curr).x = x;
4992 (*curr).y = y;
4993 (*curr).is_mapped = true;
4994 return;
4995 }
4996 curr = (*curr).next;
4997 }
4998 }
4999 fn display_srv_composite() {
5000 let bg_color = 0x1A1A1A;
5001 comp_draw_rect(comp_root_window, 0, 0, comp_width, comp_height, bg_color);
5002
5003 let mut curr = display_srv_surfaces;
5004 while curr != 0 as ptr<WaylandSurface> {
5005 if (*curr).is_mapped && (*curr).buffer != 0 as ptr<WaylandBuffer> {
5006 let buf_info = (*curr).buffer;
5007 let mut phys_base: u64 = 0;
5008 for i in 0..256 {
5009 if global_shm_table[i].shm_id == (*buf_info).shm_id {
5010 phys_base = global_shm_table[i].phys_base;
5011 break;
5012 }
5013 }
5014 if phys_base != 0 {
5015 let p_pixels = phys_base as ptr<u32>;
5016 for h in 0..(*buf_info).height {
5017 for w in 0..(*buf_info).width {
5018 let sx = (*curr).x + w as i32;
5019 let sy = (*curr).y + h as i32;
5020 if sx >= 0 && sx < comp_width as i32 && sy >= 0 && sy < comp_height as i32 {
5021 let color = *(p_pixels as u64 + (h * (*buf_info).width + w) as u64 * 4) as ptr<u32>;
5022 if (*color & 0xFF000000) != 0 {
5023 *(comp_back_buffer as u64 + (sy as u32 * comp_width + sx as u32) as u64 * 4) as ptr<u32> = *color;
5024 }
5025 }
5026 }
5027 }
5028 }
5029 }
5030 curr = (*curr).next;
5031 }
5032 memcpy(fb_ptr as ptr<u8>, comp_back_buffer as ptr<u8>, (comp_width * comp_height * 4) as u64);
5033 }
5034 struct XhciIsochTrb {
5035 data_buffer_ptr: u64,
5036 tlc_tdpc_int_cc: u32,
5037 flags: u32,
5038 }
5039 fn xhci_queue_isoch_transfer(ring: ptr<u8>, phys_buf: u64, length: u32, frame_id: u32) {
5040 let trb = ring as ptr<XhciIsochTrb>;
5041 (*trb).data_buffer_ptr = phys_buf;
5042 (*trb).tlc_tdpc_int_cc = length & 0x1FFFF;
5043 (*trb).flags = (frame_id << 20) | (32 << 10) | 1;
5044 }
5045 fn math_exp(x: f32) -> f32 {
5046 let mut sum: f32 = 1.0;
5047 let mut term: f32 = 1.0;
5048 for i in 1..20 {
5049 term = term * x / (i as f32);
5050 sum = sum + term;
5051 }
5052 return sum;
5053 }
5054 struct Tensor2D {
5055 rows: u32,
5056 cols: u32,
5057 data: ptr<f32>,
5058 }
5059 fn tensor_create(rows: u32, cols: u32) -> ptr<Tensor2D> {
5060 let t = pmm_alloc_blocks(1) as ptr<Tensor2D>;
5061 (*t).rows = rows;
5062 (*t).cols = cols;
5063 let bytes = rows * cols * 4;
5064 let pages = (bytes / PAGE_SIZE as u32) + 1;
5065 (*t).data = pmm_alloc_blocks(pages as u64) as ptr<f32>;
5066 memset((*t).data as ptr<u8>, 0, (pages * PAGE_SIZE as u32) as u64);
5067 return t;
5068 }
5069 fn tensor_destroy(t: ptr<Tensor2D>) {
5070 let bytes = (*t).rows * (*t).cols * 4;
5071 let pages = (bytes / PAGE_SIZE as u32) + 1;
5072 pmm_free_blocks((*t).data as u64, pages as u64);
5073 pmm_free_blocks(t as u64, 1);
5074 }
5075 fn tensor_matmul(a: ptr<Tensor2D>, b: ptr<Tensor2D>, out: ptr<Tensor2D>) {
5076 if (*a).cols != (*b).rows { return; }
5077 if (*out).rows != (*a).rows || (*out).cols != (*b).cols { return; }
5078
5079 for i in 0..(*a).rows {
5080 for j in 0..(*b).cols {
5081 let mut sum: f32 = 0.0;
5082 for k in 0..(*a).cols {
5083 let val_a = *((*a).data as u64 + (i * (*a).cols + k) as u64 * 4) as ptr<f32>;
5084 let val_b = *((*b).data as u64 + (k * (*b).cols + j) as u64 * 4) as ptr<f32>;
5085 sum = sum + (*val_a * *val_b);
5086 }
5087 *((*out).data as u64 + (i * (*out).cols + j) as u64 * 4) as ptr<f32> = sum;
5088 }
5089 }
5090 }
5091 fn tensor_relu(t: ptr<Tensor2D>) {
5092 let total = (*t).rows * (*t).cols;
5093 for i in 0..total {
5094 let val_ptr = ((*t).data as u64 + i as u64 * 4) as ptr<f32>;
5095 if *val_ptr < 0.0 {
5096 *val_ptr = 0.0;
5097 }
5098 }
5099 }
5100 fn tensor_sigmoid(t: ptr<Tensor2D>) {
5101 let total = (*t).rows * (*t).cols;
5102 for i in 0..total {
5103 let val_ptr = ((*t).data as u64 + i as u64 * 4) as ptr<f32>;
5104 let e_x = math_exp(-(*val_ptr));
5105 *val_ptr = 1.0 / (1.0 + e_x);
5106 }
5107 }
5108 fn tensor_softmax(t: ptr<Tensor2D>) {
5109 for i in 0..(*t).rows {
5110 let mut max_val = *((*t).data as u64 + (i * (*t).cols) as u64 * 4) as ptr<f32>;
5111 for j in 1..(*t).cols {
5112 let v = *((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5113 if v > max_val { max_val = v; }
5114 }
5115
5116 let mut sum_exp: f32 = 0.0;
5117 for j in 0..(*t).cols {
5118 let val_ptr = ((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5119 let e = math_exp(*val_ptr - max_val);
5120 *val_ptr = e;
5121 sum_exp = sum_exp + e;
5122 }
5123
5124 for j in 0..(*t).cols {
5125 let val_ptr = ((*t).data as u64 + (i * (*t).cols + j) as u64 * 4) as ptr<f32>;
5126 *val_ptr = *val_ptr / sum_exp;
5127 }
5128 }
5129 }
5130 const FW_ACTION_ALLOW: u8 = 0;
5131 const FW_ACTION_DROP: u8 = 1;
5132 const FW_ACTION_REJECT: u8 = 2;
5133 const FW_PROTO_TCP: u8 = 6;
5134 const FW_PROTO_UDP: u8 = 17;
5135 const FW_PROTO_ICMP: u8 = 1;
5136 struct FirewallRule {
5137 src_ip: Ipv4Addr,
5138 src_mask: Ipv4Addr,
5139 dst_ip: Ipv4Addr,
5140 dst_mask: Ipv4Addr,
5141 src_port_min: u16,
5142 src_port_max: u16,
5143 dst_port_min: u16,
5144 dst_port_max: u16,
5145 protocol: u8,
5146 action: u8,
5147 is_active: bool,
5148 hit_count: u64,
5149 }
5150 struct FwConnectionState {
5151 src_ip: Ipv4Addr,
5152 dst_ip: Ipv4Addr,
5153 src_port: u16,
5154 dst_port: u16,
5155 protocol: u8,
5156 state: u8,
5157 last_activity: u64,
5158 is_active: bool,
5159 }
5160 let mut global_fw_rules: [FirewallRule; 512];
5161 let mut global_fw_states: [FwConnectionState; 4096];
5162 let mut fw_lock: Spinlock;
5163 let mut fw_enabled: bool = true;
5164 let mut fw_syn_cookie_secret: u32 = 0;
5165 fn fw_init() {
5166 spin_init(&fw_lock);
5167 for i in 0..512 { global_fw_rules[i].is_active = false; }
5168 for i in 0..4096 { global_fw_states[i].is_active = false; }
5169 fw_syn_cookie_secret = rand_next() as u32;
5170 }
5171 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 {
5172 spin_lock(&fw_lock);
5173 for i in 0..512 {
5174 if !global_fw_rules[i].is_active {
5175 global_fw_rules[i].src_ip = src_ip;
5176 global_fw_rules[i].src_mask = src_mask;
5177 global_fw_rules[i].dst_ip = dst_ip;
5178 global_fw_rules[i].dst_mask = dst_mask;
5179 global_fw_rules[i].src_port_min = 0;
5180 global_fw_rules[i].src_port_max = 65535;
5181 global_fw_rules[i].dst_port_min = p_min;
5182 global_fw_rules[i].dst_port_max = p_max;
5183 global_fw_rules[i].protocol = proto;
5184 global_fw_rules[i].action = action;
5185 global_fw_rules[i].hit_count = 0;
5186 global_fw_rules[i].is_active = true;
5187 spin_unlock(&fw_lock);
5188 return true;
5189 }
5190 }
5191 spin_unlock(&fw_lock);
5192 return false;
5193 }
5194 fn fw_match_ip(ip: Ipv4Addr, rule_ip: Ipv4Addr, mask: Ipv4Addr) -> bool {
5195 for i in 0..4 {
5196 if (ip.addr[i] & mask.addr[i]) != (rule_ip.addr[i] & mask.addr[i]) {
5197 return false;
5198 }
5199 }
5200 return true;
5201 }
5202 fn fw_track_connection(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, src_port: u16, dst_port: u16, proto: u8, tcp_flags: u16) -> bool {
5203 for i in 0..4096 {
5204 if global_fw_states[i].is_active {
5205 let mut match_fwd = true;
5206 let mut match_rev = true;
5207 for j in 0..4 {
5208 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; }
5209 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; }
5210 }
5211 if global_fw_states[i].protocol != proto { match_fwd = false; match_rev = false; }
5212 if global_fw_states[i].src_port != src_port || global_fw_states[i].dst_port != dst_port { match_fwd = false; }
5213 if global_fw_states[i].src_port != dst_port || global_fw_states[i].dst_port != src_port { match_rev = false; }
5214
5215 if match_fwd || match_rev {
5216 global_fw_states[i].last_activity = current_time_tick;
5217 if proto == FW_PROTO_TCP && (tcp_flags & 0x01) != 0 {
5218 global_fw_states[i].is_active = false;
5219 }
5220 return true;
5221 }
5222 }
5223 }
5224
5225 if proto == FW_PROTO_TCP && (tcp_flags & 0x02) != 0 && (tcp_flags & 0x10) == 0 {
5226 for i in 0..4096 {
5227 if !global_fw_states[i].is_active {
5228 global_fw_states[i].src_ip = src_ip;
5229 global_fw_states[i].dst_ip = dst_ip;
5230 global_fw_states[i].src_port = src_port;
5231 global_fw_states[i].dst_port = dst_port;
5232 global_fw_states[i].protocol = proto;
5233 global_fw_states[i].state = 1;
5234 global_fw_states[i].last_activity = current_time_tick;
5235 global_fw_states[i].is_active = true;
5236 return true;
5237 }
5238 }
5239 }
5240
5241 return false;
5242 }
5243 fn fw_inspect_packet(packet: ptr<u8>, length: u32) -> u8 {
5244 if !fw_enabled { return FW_ACTION_ALLOW; }
5245
5246 let eth = packet as ptr<EthernetHeader>;
5247 if htons((*eth).ethertype) != 0x0800 { return FW_ACTION_ALLOW; }
5248
5249 let iph = (packet as u64 + sizeof(EthernetHeader) as u64) as ptr<Ipv4Header>;
5250 let proto = (*iph).protocol;
5251 let mut src_port: u16 = 0;
5252 let mut dst_port: u16 = 0;
5253 let mut tcp_flags: u16 = 0;
5254
5255 if proto == FW_PROTO_TCP {
5256 let tcph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<TcpHeader>;
5257 src_port = htons((*tcph).src_port);
5258 dst_port = htons((*tcph).dest_port);
5259 tcp_flags = htons((*tcph).data_offset_flags) & 0x01FF;
5260 } else if proto == FW_PROTO_UDP {
5261 let udph = (packet as u64 + sizeof(EthernetHeader) as u64 + sizeof(Ipv4Header) as u64) as ptr<UdpHeader>;
5262 src_port = htons((*udph).src_port);
5263 dst_port = htons((*udph).dest_port);
5264 }
5265
5266 spin_lock(&fw_lock);
5267 let tracked = fw_track_connection((*iph).src_ip, (*iph).dest_ip, src_port, dst_port, proto, tcp_flags);
5268 if tracked {
5269 spin_unlock(&fw_lock);
5270 return FW_ACTION_ALLOW;
5271 }
5272
5273 let mut final_action = FW_ACTION_DROP;
5274
5275 for i in 0..512 {
5276 if global_fw_rules[i].is_active {
5277 let mut match_rule = true;
5278 if global_fw_rules[i].protocol != 0 && global_fw_rules[i].protocol != proto { match_rule = false; }
5279 if !fw_match_ip((*iph).src_ip, global_fw_rules[i].src_ip, global_fw_rules[i].src_mask) { match_rule = false; }
5280 if !fw_match_ip((*iph).dest_ip, global_fw_rules[i].dst_ip, global_fw_rules[i].dst_mask) { match_rule = false; }
5281 if proto == FW_PROTO_TCP || proto == FW_PROTO_UDP {
5282 if src_port < global_fw_rules[i].src_port_min || src_port > global_fw_rules[i].src_port_max { match_rule = false; }
5283 if dst_port < global_fw_rules[i].dst_port_min || dst_port > global_fw_rules[i].dst_port_max { match_rule = false; }
5284 }
5285
5286 if match_rule {
5287 global_fw_rules[i].hit_count = global_fw_rules[i].hit_count + 1;
5288 final_action = global_fw_rules[i].action;
5289 break;
5290 }
5291 }
5292 }
5293
5294 spin_unlock(&fw_lock);
5295 return final_action;
5296 }
5297 struct HciCommandHeader {
5298 opcode: u16,
5299 param_length: u8,
5300 }
5301 struct HciAclHeader {
5302 handle_flags: u16,
5303 data_length: u16,
5304 }
5305 struct L2capHeader {
5306 length: u16,
5307 channel_id: u16,
5308 }
5309 const HCI_CMD_RESET: u16 = 0x0C03;
5310 const HCI_CMD_READ_BD_ADDR: u16 = 0x1009;
5311 const HCI_CMD_INQUIRY: u16 = 0x0401;
5312 const HCI_CMD_CREATE_CONNECTION: u16 = 0x0405;
5313 let mut bt_hci_tx_ring: ptr<u8>;
5314 let mut bt_hci_rx_ring: ptr<u8>;
5315 fn bt_init_controller() {
5316 bt_hci_tx_ring = pmm_alloc_blocks(1) as ptr<u8>;
5317 bt_hci_rx_ring = pmm_alloc_blocks(1) as ptr<u8>;
5318 memset(bt_hci_tx_ring, 0, PAGE_SIZE);
5319 memset(bt_hci_rx_ring, 0, PAGE_SIZE);
5320 }
5321 fn bt_send_hci_command(opcode: u16, params: ptr<u8>, param_len: u8) {
5322 let hdr = bt_hci_tx_ring as ptr<HciCommandHeader>;
5323 (*hdr).opcode = opcode;
5324 (*hdr).param_length = param_len;
5325 if param_len > 0 {
5326 let payload = (bt_hci_tx_ring as u64 + sizeof(HciCommandHeader) as u64) as ptr<u8>;
5327 memcpy(payload, params, param_len as u64);
5328 }
5329 let total_len = sizeof(HciCommandHeader) as u64 + param_len as u64;
5330 xhci_queue_isoch_transfer(0 as ptr<u8>, bt_hci_tx_ring as u64, total_len as u32, 0);
5331 }
5332 fn bt_send_l2cap(handle: u16, cid: u16, data: ptr<u8>, len: u16) {
5333 let acl_hdr = bt_hci_tx_ring as ptr<HciAclHeader>;
5334 (*acl_hdr).handle_flags = handle | 0x2000;
5335 (*acl_hdr).data_length = sizeof(L2capHeader) as u16 + len;
5336
5337 let l2cap_hdr = (bt_hci_tx_ring as u64 + sizeof(HciAclHeader) as u64) as ptr<L2capHeader>;
5338 (*l2cap_hdr).length = len;
5339 (*l2cap_hdr).channel_id = cid;
5340
5341 let payload = (bt_hci_tx_ring as u64 + sizeof(HciAclHeader) as u64 + sizeof(L2capHeader) as u64) as ptr<u8>;
5342 memcpy(payload, data, len as u64);
5343
5344 let total_len = sizeof(HciAclHeader) as u64 + (*acl_hdr).data_length as u64;
5345 xhci_queue_isoch_transfer(0 as ptr<u8>, bt_hci_tx_ring as u64, total_len as u32, 0);
5346 }
5347 struct Jbd2Header {
5348 h_magic: u32,
5349 h_blocktype: u32,
5350 h_sequence: u32,
5351 }
5352 struct Jbd2BlockTag {
5353 t_blocknr: u32,
5354 t_flags: u16,
5355 }
5356 const JBD2_MAGIC_NUMBER: u32 = 0xC03B3998;
5357 const JBD2_DESCRIPTOR_BLOCK: u32 = 1;
5358 const JBD2_COMMIT_BLOCK: u32 = 2;
5359 const JBD2_SUPERBLOCK_V1: u32 = 3;
5360 const JBD2_SUPERBLOCK_V2: u32 = 4;
5361 const JBD2_REVOKE_BLOCK: u32 = 5;
5362 let mut jbd2_journal_start: u32 = 0;
5363 let mut jbd2_journal_end: u32 = 0;
5364 let mut jbd2_current_seq: u32 = 1;
5365 fn jbd2_init(start_block: u32, end_block: u32) {
5366 jbd2_journal_start = start_block;
5367 jbd2_journal_end = end_block;
5368 jbd2_current_seq = 1;
5369 }
5370 fn jbd2_start_transaction() -> u32 {
5371 let seq = jbd2_current_seq;
5372 jbd2_current_seq = jbd2_current_seq + 1;
5373 return seq;
5374 }
5375 fn jbd2_write_descriptor(seq: u32, target_blocks: ptr<u32>, count: u32) -> u32 {
5376 let buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
5377 memset(buf, 0, ext2_block_size as u64);
5378
5379 let hdr = buf as ptr<Jbd2Header>;
5380 (*hdr).h_magic = htonl(JBD2_MAGIC_NUMBER);
5381 (*hdr).h_blocktype = htonl(JBD2_DESCRIPTOR_BLOCK);
5382 (*hdr).h_sequence = htonl(seq);
5383
5384 let mut offset = sizeof(Jbd2Header) as u64;
5385 for i in 0..count {
5386 let tag = (buf as u64 + offset) as ptr<Jbd2BlockTag>;
5387 (*tag).t_blocknr = htonl(*(target_blocks as u64 + i as u64 * 4) as ptr<u32>);
5388 (*tag).t_flags = 0;
5389 if i == count - 1 { (*tag).t_flags = htons(8); }
5390 offset = offset + sizeof(Jbd2BlockTag) as u64;
5391 }
5392
5393 let lba = fat32_cluster_to_lba(jbd2_journal_start);
5394 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, lba as u64, (ext2_block_size / 512) as u32, buf as u64);
5395 pmm_free_blocks(buf as u64, (ext2_block_size / PAGE_SIZE as u32) + 1);
5396 return jbd2_journal_start + 1;
5397 }
5398 fn jbd2_commit_transaction(seq: u32, cur_journal_block: u32) {
5399 let buf = pmm_alloc_blocks((ext2_block_size / PAGE_SIZE as u32) + 1) as ptr<u8>;
5400 memset(buf, 0, ext2_block_size as u64);
5401
5402 let hdr = buf as ptr<Jbd2Header>;
5403 (*hdr).h_magic = htonl(JBD2_MAGIC_NUMBER);
5404 (*hdr).h_blocktype = htonl(JBD2_COMMIT_BLOCK);
5405 (*hdr).h_sequence = htonl(seq);
5406
5407 let lba = fat32_cluster_to_lba(cur_journal_block);
5408 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, lba as u64, (ext2_block_size / 512) as u32, buf as u64);
5409 pmm_free_blocks(buf as u64, (ext2_block_size / PAGE_SIZE as u32) + 1);
5410 }
5411 struct UacFormatTypeI {
5412 length: u8,
5413 descriptor_type: u8,
5414 descriptor_subtype: u8,
5415 format_type: u8,
5416 num_channels: u8,
5417 subframe_size: u8,
5418 bit_resolution: u8,
5419 sample_freq_type: u8,
5420 sample_freq: [u8; 3],
5421 }
5422 fn uac_set_sample_rate(ep_addr: u8, rate: u32) {
5423 let mut setup_packet: [u8; 8];
5424 setup_packet[0] = 0x22;
5425 setup_packet[1] = 0x01;
5426 setup_packet[2] = 0x01;
5427 setup_packet[3] = 0x01;
5428 setup_packet[4] = ep_addr;
5429 setup_packet[5] = 0x00;
5430 setup_packet[6] = 0x03;
5431 setup_packet[7] = 0x00;
5432
5433 let mut data_packet: [u8; 3];
5434 data_packet[0] = (rate & 0xFF) as u8;
5435 data_packet[1] = ((rate >> 8) & 0xFF) as u8;
5436 data_packet[2] = ((rate >> 16) & 0xFF) as u8;
5437 }
5438 fn hw_rdrand_64() -> u64 {
5439 let mut val: u64 = 0;
5440 let mut retry: u32 = 10;
5441 while retry > 0 {
5442 let mut success: u8 = 0;
5443 asm {
5444 "rdrand rax\n setc bl"
5445 out rax = val;
5446 out bl = success;
5447 }
5448 if success == 1 { return val; }
5449 retry = retry - 1;
5450 }
5451 return rand_next();
5452 }
5453 fn hw_rdseed_64() -> u64 {
5454 let mut val: u64 = 0;
5455 let mut retry: u32 = 10;
5456 while retry > 0 {
5457 let mut success: u8 = 0;
5458 asm {
5459 "rdseed rax\n setc bl"
5460 out rax = val;
5461 out bl = success;
5462 }
5463 if success == 1 { return val; }
5464 retry = retry - 1;
5465 }
5466 return hw_rdrand_64();
5467 }
5468 struct VmxonRegion {
5469 revision_id: u32,
5470 data: [u8; 4092],
5471 }
5472 struct VmcsRegion {
5473 revision_id: u32,
5474 abort_indicator: u32,
5475 data: [u8; 4088],
5476 }
5477 let mut vmx_enabled: bool = false;
5478 let mut vmxon_region_phys: u64 = 0;
5479 fn vmx_check_support() -> bool {
5480 let mut ecx: u32 = 0;
5481 asm {
5482 "mov eax, 1\n cpuid"
5483 out ecx = ecx;
5484 }
5485 return (ecx & (1 << 5)) != 0;
5486 }
5487 fn vmx_enable() {
5488 let mut cr4: u64 = 0;
5489 asm { "mov %0, cr4" out cr4 = cr4; }
5490 cr4 |= (1 << 13);
5491 asm { "mov cr4, %0" in "%0" = cr4; }
5492
5493 let feature_control = rdmsr(0x3A);
5494 if (feature_control & 1) == 0 {
5495 wrmsr(0x3A, feature_control | 5);
5496 }
5497 }
5498 fn vmx_init() {
5499 if !vmx_check_support() { return; }
5500 vmx_enable();
5501
5502 let vmx_basic = rdmsr(0x480);
5503 let revision_id = (vmx_basic & 0xFFFFFFFF) as u32;
5504
5505 vmxon_region_phys = pmm_alloc_blocks(1);
5506 memset(vmxon_region_phys as ptr<u8>, 0, PAGE_SIZE);
5507 *(vmxon_region_phys as ptr<u32>) = revision_id;
5508
5509 let mut success: u8 = 0;
5510 asm {
5511 "vmxon [%0]\n setz al\n setc ah"
5512 in "%0" = &vmxon_region_phys;
5513 out al = success;
5514 }
5515 if success == 0 { vmx_enabled = true; }
5516 }
5517 fn vmx_create_vm() -> ptr<VmcsRegion> {
5518 if !vmx_enabled { return 0 as ptr<VmcsRegion>; }
5519
5520 let vmx_basic = rdmsr(0x480);
5521 let revision_id = (vmx_basic & 0xFFFFFFFF) as u32;
5522
5523 let vmcs_phys = pmm_alloc_blocks(1);
5524 memset(vmcs_phys as ptr<u8>, 0, PAGE_SIZE);
5525 *(vmcs_phys as ptr<u32>) = revision_id;
5526
5527 asm {
5528 "vmclear [%0]"
5529 in "%0" = &vmcs_phys;
5530 }
5531
5532 asm {
5533 "vmptrld [%0]"
5534 in "%0" = &vmcs_phys;
5535 }
5536
5537 return vmcs_phys as ptr<VmcsRegion>;
5538 }
5539 struct WasmModule {
5540 magic: u32,
5541 version: u32,
5542 memory_pages: u32,
5543 memory_base: u64,
5544 code_base: ptr<u8>,
5545 code_size: u64,
5546 }
5547 const WASM_MAGIC: u32 = 0x6D736100;
5548 fn wasm_parse_leb128(data: ptr<u8>, offset: ptr<u64>) -> u64 {
5549 let mut result: u64 = 0;
5550 let mut shift: u64 = 0;
5551 loop {
5552 let byte = *(data as u64 + *offset) as ptr<u8>;
5553 *offset = *offset + 1;
5554 result |= ((*byte & 0x7F) as u64) << shift;
5555 shift = shift + 7;
5556 if (*byte & 0x80) == 0 { break; }
5557 }
5558 return result;
5559 }
5560 fn wasm_load_module(wasm_data: ptr<u8>, size: u64) -> ptr<WasmModule> {
5561 let magic = *(wasm_data as ptr<u32>);
5562 if magic != WASM_MAGIC { return 0 as ptr<WasmModule>; }
5563
5564 let version = *((wasm_data as u64 + 4) as ptr<u32>);
5565 if version != 1 { return 0 as ptr<WasmModule>; }
5566
5567 let module = pmm_alloc_blocks(1) as ptr<WasmModule>;
5568 memset(module as ptr<u8>, 0, sizeof(WasmModule) as u64);
5569 (*module).magic = magic;
5570 (*module).version = version;
5571
5572 let mut offset: u64 = 8;
5573 while offset < size {
5574 let section_id = *(wasm_data as u64 + offset) as ptr<u8>;
5575 offset = offset + 1;
5576 let section_size = wasm_parse_leb128(wasm_data, &offset);
5577
5578 if *section_id == 10 {
5579 (*module).code_base = (wasm_data as u64 + offset) as ptr<u8>;
5580 (*module).code_size = section_size;
5581 } else if *section_id == 5 {
5582 let _num_mems = wasm_parse_leb128(wasm_data, &offset);
5583 let flags = wasm_parse_leb128(wasm_data, &offset);
5584 let initial_pages = wasm_parse_leb128(wasm_data, &offset);
5585 (*module).memory_pages = initial_pages as u32;
5586 (*module).memory_base = pmm_alloc_blocks(initial_pages * 16);
5587 memset((*module).memory_base as ptr<u8>, 0, initial_pages * 65536);
5588 }
5589 offset = offset + section_size;
5590 }
5591 return module;
5592 }
5593 fn wasm_execute_function(module: ptr<WasmModule>, func_offset: u64) {
5594 let mut pc = func_offset;
5595 let mut stack: [u64; 1024];
5596 let mut sp: u32 = 0;
5597
5598 let code = (*module).code_base;
5599 loop {
5600 let opcode = *(code as u64 + pc) as ptr<u8>;
5601 pc = pc + 1;
5602
5603 if *opcode == 0x0B {
5604 break;
5605 } else if *opcode == 0x20 {
5606 let local_idx = wasm_parse_leb128(code, &pc);
5607 stack[sp as usize] = 0;
5608 sp = sp + 1;
5609 } else if *opcode == 0x41 {
5610 let val = wasm_parse_leb128(code, &pc);
5611 stack[sp as usize] = val;
5612 sp = sp + 1;
5613 } else if *opcode == 0x6A {
5614 sp = sp - 1; let b = stack[sp as usize] as i32;
5615 sp = sp - 1; let a = stack[sp as usize] as i32;
5616 stack[sp as usize] = (a + b) as u64;
5617 sp = sp + 1;
5618 } else if *opcode == 0x6B {
5619 sp = sp - 1; let b = stack[sp as usize] as i32;
5620 sp = sp - 1; let a = stack[sp as usize] as i32;
5621 stack[sp as usize] = (a - b) as u64;
5622 sp = sp + 1;
5623 } else if *opcode == 0x6C {
5624 sp = sp - 1; let b = stack[sp as usize] as i32;
5625 sp = sp - 1; let a = stack[sp as usize] as i32;
5626 stack[sp as usize] = (a * b) as u64;
5627 sp = sp + 1;
5628 }
5629 }
5630 }
5631 const DB_TYPE_STRING: u8 = 1;
5632 const DB_TYPE_LIST: u8 = 2;
5633 const DB_TYPE_INT: u8 = 3;
5634 struct AegisDbEntry {
5635 key: [u8; 32],
5636 val_type: u8,
5637 val_int: u64,
5638 val_str: ptr<u8>,
5639 val_size: u64,
5640 next: ptr<AegisDbEntry>,
5641 }
5642 let mut global_db_hash_table: [ptr<AegisDbEntry>; 1024];
5643 let mut db_lock: Spinlock;
5644 fn db_hash_key(key: ptr<u8>) -> u32 {
5645 let mut hash: u32 = 5381;
5646 let mut i: u64 = 0;
5647 while *(key + i) != 0 {
5648 hash = ((hash << 5) + hash) + (*(key + i) as u32);
5649 i = i + 1;
5650 }
5651 return hash % 1024;
5652 }
5653 fn db_init() {
5654 spin_init(&db_lock);
5655 for i in 0..1024 {
5656 global_db_hash_table[i] = 0 as ptr<AegisDbEntry>;
5657 }
5658 }
5659 fn db_set_string(key: ptr<u8>, value: ptr<u8>) {
5660 spin_lock(&db_lock);
5661 let idx = db_hash_key(key);
5662
5663 let mut curr = global_db_hash_table[idx as usize];
5664 while curr != 0 as ptr<AegisDbEntry> {
5665 if strcmp(&((*curr).key[0]) as ptr<u8>, key) == 0 {
5666 if (*curr).val_str != 0 as ptr<u8> {
5667 pmm_free_blocks((*curr).val_str as u64, ((*curr).val_size / PAGE_SIZE) + 1);
5668 }
5669 let len = strlen(value) + 1;
5670 (*curr).val_type = DB_TYPE_STRING;
5671 (*curr).val_size = len;
5672 (*curr).val_str = pmm_alloc_blocks((len / PAGE_SIZE) + 1) as ptr<u8>;
5673 strcpy((*curr).val_str, value);
5674 spin_unlock(&db_lock);
5675 return;
5676 }
5677 curr = (*curr).next;
5678 }
5679
5680 let new_entry = pmm_alloc_blocks(1) as ptr<AegisDbEntry>;
5681 memset(new_entry as ptr<u8>, 0, sizeof(AegisDbEntry) as u64);
5682 strcpy(&((*new_entry).key[0]) as ptr<u8>, key);
5683 let len = strlen(value) + 1;
5684 (*new_entry).val_type = DB_TYPE_STRING;
5685 (*new_entry).val_size = len;
5686 (*new_entry).val_str = pmm_alloc_blocks((len / PAGE_SIZE) + 1) as ptr<u8>;
5687 strcpy((*new_entry).val_str, value);
5688
5689 (*new_entry).next = global_db_hash_table[idx as usize];
5690 global_db_hash_table[idx as usize] = new_entry;
5691 spin_unlock(&db_lock);
5692 }
5693 fn db_get_string(key: ptr<u8>, out_buf: ptr<u8>) -> bool {
5694 spin_lock(&db_lock);
5695 let idx = db_hash_key(key);
5696 let mut curr = global_db_hash_table[idx as usize];
5697 while curr != 0 as ptr<AegisDbEntry> {
5698 if strcmp(&((*curr).key[0]) as ptr<u8>, key) == 0 && (*curr).val_type == DB_TYPE_STRING {
5699 strcpy(out_buf, (*curr).val_str);
5700 spin_unlock(&db_lock);
5701 return true;
5702 }
5703 curr = (*curr).next;
5704 }
5705 spin_unlock(&db_lock);
5706 return false;
5707 }
5708 const PTRACE_TRACEME: u32 = 0;
5709 const PTRACE_PEEKTEXT: u32 = 1;
5710 const PTRACE_POKETEXT: u32 = 4;
5711 const PTRACE_CONT: u32 = 7;
5712 const PTRACE_SINGLESTEP: u32 = 9;
5713 const PTRACE_GETREGS: u32 = 12;
5714 const PTRACE_SETREGS: u32 = 13;
5715 const PTRACE_ATTACH: u32 = 16;
5716 const PTRACE_DETACH: u32 = 17;
5717 struct PtraceState {
5718 is_traced: bool,
5719 tracer_pid: u64,
5720 stop_signal: u32,
5721 saved_opcode: u8,
5722 breakpoint_addr: u64,
5723 }
5724 fn ptrace_attach(target_pid: u64, tracer_pid: u64) -> i32 {
5725 let mut curr = process_queue;
5726 while curr != 0 as ptr<ProcessControlBlock> {
5727 if (*curr).pid == target_pid {
5728 let proc_ext = curr as ptr<ProcessControlBlockExt>;
5729 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
5730 if (*pstate).is_traced { return -1; }
5731 (*pstate).is_traced = true;
5732 (*pstate).tracer_pid = tracer_pid;
5733 signal_send(target_pid, 19);
5734 return 0;
5735 }
5736 curr = (*curr).next;
5737 }
5738 return -1;
5739 }
5740 fn ptrace_getregs(target_pid: u64, out_ctx: ptr<CpuContext>) -> i32 {
5741 let mut curr = process_queue;
5742 while curr != 0 as ptr<ProcessControlBlock> {
5743 if (*curr).pid == target_pid {
5744 let proc_ext = curr as ptr<ProcessControlBlockExt>;
5745 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
5746 if !(*pstate).is_traced { return -1; }
5747 memcpy(out_ctx as ptr<u8>, (*curr).context as ptr<u8>, sizeof(CpuContext) as u64);
5748 return 0;
5749 }
5750 curr = (*curr).next;
5751 }
5752 return -1;
5753 }
5754 fn ptrace_set_breakpoint(target_pid: u64, addr: u64) -> i32 {
5755 let mut curr = process_queue;
5756 while curr != 0 as ptr<ProcessControlBlock> {
5757 if (*curr).pid == target_pid {
5758 let proc_ext = curr as ptr<ProcessControlBlockExt>;
5759 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
5760 if !(*pstate).is_traced { return -1; }
5761
5762 let old_cr3 = rdmsr(0);
5763 asm { "mov cr3, %0" in "%0" = (*curr).cr3_phys; }
5764
5765 (*pstate).saved_opcode = *(addr as ptr<u8>);
5766 *(addr as ptr<u8>) = 0xCC;
5767 (*pstate).breakpoint_addr = addr;
5768
5769 asm { "mov cr3, %0" in "%0" = old_cr3; }
5770 return 0;
5771 }
5772 curr = (*curr).next;
5773 }
5774 return -1;
5775 }
5776 fn exc_breakpoint_handler_adv() {
5777 let proc_ext = current_process as ptr<ProcessControlBlockExt>;
5778 let pstate = (proc_ext as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<PtraceState>;
5779
5780 if (*pstate).is_traced {
5781 (*current_process).state = 0;
5782 let rip = (*(*current_process).context).rip - 1;
5783
5784 if rip == (*pstate).breakpoint_addr {
5785 *(rip as ptr<u8>) = (*pstate).saved_opcode;
5786 (*(*current_process).context).rip = rip;
5787 }
5788
5789 signal_send((*pstate).tracer_pid, 17);
5790 scheduler_tick();
5791 }
5792 }
5793 const MSR_IA32_PERF_GLOBAL_CTRL: u32 = 0x38F;
5794 const MSR_IA32_PERFEVTSEL0: u32 = 0x186;
5795 const MSR_IA32_PERFEVTSEL1: u32 = 0x187;
5796 const MSR_IA32_PMC0: u32 = 0xC1;
5797 const MSR_IA32_PMC1: u32 = 0xC2;
5798 const MSR_IA32_FIXED_CTR_CTRL: u32 = 0x38D;
5799 const MSR_IA32_FIXED_CTR0: u32 = 0x309;
5800 const MSR_IA32_FIXED_CTR1: u32 = 0x30A;
5801 const MSR_IA32_FIXED_CTR2: u32 = 0x30B;
5802 struct PmuStats {
5803 instructions: u64,
5804 core_cycles: u64,
5805 ref_cycles: u64,
5806 cache_misses: u64,
5807 branch_misses: u64,
5808 }
5809 let mut global_pmu_stats: PmuStats;
5810 fn pmu_init() {
5811 let mut cpuid_eax: u32 = 0;
5812 let mut cpuid_ebx: u32 = 0;
5813 let mut cpuid_ecx: u32 = 0;
5814 let mut cpuid_edx: u32 = 0;
5815 cpuid(0x0A, 0, &mut cpuid_eax, &mut cpuid_ebx, &mut cpuid_ecx, &mut cpuid_edx);
5816 let pmu_version = cpuid_eax & 0xFF;
5817 if pmu_version < 2 { return; }
5818 wrmsr(MSR_IA32_PERF_GLOBAL_CTRL, 0);
5819 wrmsr(MSR_IA32_FIXED_CTR_CTRL, 0x333);
5820 let evt_cache_miss = (0x41 << 8) | 0x2E | (1 << 16) | (1 << 22);
5821 wrmsr(MSR_IA32_PERFEVTSEL0, evt_cache_miss);
5822
5823 let evt_branch_miss = (0x00 << 8) | 0xC5 | (1 << 16) | (1 << 22);
5824 wrmsr(MSR_IA32_PERFEVTSEL1, evt_branch_miss);
5825 wrmsr(MSR_IA32_PERF_GLOBAL_CTRL, (1 << 32) | (1 << 33) | (1 << 34) | 1 | 2);
5826 }
5827 fn pmu_read_stats() {
5828 global_pmu_stats.instructions = rdmsr(MSR_IA32_FIXED_CTR0);
5829 global_pmu_stats.core_cycles = rdmsr(MSR_IA32_FIXED_CTR1);
5830 global_pmu_stats.ref_cycles = rdmsr(MSR_IA32_FIXED_CTR2);
5831 global_pmu_stats.cache_misses = rdmsr(MSR_IA32_PMC0);
5832 global_pmu_stats.branch_misses = rdmsr(MSR_IA32_PMC1);
5833 }
5834 const EC_CMD_PORT: u16 = 0x66;
5835 const EC_DATA_PORT: u16 = 0x62;
5836 const EC_CMD_READ: u8 = 0x80;
5837 const EC_CMD_WRITE: u8 = 0x81;
5838 const EC_STAT_OBF: u8 = 0x01;
5839 const EC_STAT_IBF: u8 = 0x02;
5840 fn acpi_ec_wait_write() {
5841 let mut timeout = 100000;
5842 while (inb(EC_CMD_PORT) & EC_STAT_IBF) != 0 && timeout > 0 {
5843 cpu_pause();
5844 timeout = timeout - 1;
5845 }
5846 }
5847 fn acpi_ec_wait_read() {
5848 let mut timeout = 100000;
5849 while (inb(EC_CMD_PORT) & EC_STAT_OBF) == 0 && timeout > 0 {
5850 cpu_pause();
5851 timeout = timeout - 1;
5852 }
5853 }
5854 fn acpi_ec_read(addr: u8) -> u8 {
5855 acpi_ec_wait_write();
5856 outb(EC_CMD_PORT, EC_CMD_READ);
5857 acpi_ec_wait_write();
5858 outb(EC_DATA_PORT, addr);
5859 acpi_ec_wait_read();
5860 return inb(EC_DATA_PORT);
5861 }
5862 fn acpi_ec_write(addr: u8, data: u8) {
5863 acpi_ec_wait_write();
5864 outb(EC_CMD_PORT, EC_CMD_WRITE);
5865 acpi_ec_wait_write();
5866 outb(EC_DATA_PORT, addr);
5867 acpi_ec_wait_write();
5868 outb(EC_DATA_PORT, data);
5869 }
5870 struct BatteryState {
5871 is_present: bool,
5872 is_charging: bool,
5873 capacity_percent: u8,
5874 voltage_mv: u16,
5875 temperature_c: u8,
5876 }
5877 let mut global_battery_state: BatteryState;
5878 fn acpi_update_battery_state() {
5879 let bat_status = acpi_ec_read(0x10);
5880 global_battery_state.is_present = (bat_status & 0x01) != 0;
5881 global_battery_state.is_charging = (bat_status & 0x02) != 0;
5882
5883 if global_battery_state.is_present {
5884 let cap_high = acpi_ec_read(0x11);
5885 let cap_low = acpi_ec_read(0x12);
5886 let max_cap = 10000;
5887 let current_cap = ((cap_high as u16) << 8) | (cap_low as u16);
5888 global_battery_state.capacity_percent = ((current_cap as u32 * 100) / max_cap as u32) as u8;
5889
5890 let volt_high = acpi_ec_read(0x13);
5891 let volt_low = acpi_ec_read(0x14);
5892 global_battery_state.voltage_mv = ((volt_high as u16) << 8) | (volt_low as u16);
5893
5894 let temp_raw = acpi_ec_read(0x15);
5895 global_battery_state.temperature_c = temp_raw - 27;
5896 }
5897 }
5898 struct UsbHubDescriptor {
5899 length: u8,
5900 descriptor_type: u8,
5901 num_ports: u8,
5902 hub_characteristics: u16,
5903 power_on_to_power_good: u8,
5904 hub_control_current: u8,
5905 device_removable: u8,
5906 port_power_ctrl_mask: u8,
5907 }
5908 struct UsbHubPort {
5909 port_id: u8,
5910 is_connected: bool,
5911 is_enabled: bool,
5912 is_superspeed: bool,
5913 device_address: u8,
5914 }
5915 struct UsbHubDevice {
5916 address: u8,
5917 num_ports: u8,
5918 ports: [UsbHubPort; 16],
5919 is_active: bool,
5920 }
5921 let mut global_usb_hubs: [UsbHubDevice; 8];
5922 let mut usb_hub_count: u32 = 0;
5923 fn usb_hub_init_device(device_addr: u8) {
5924 if usb_hub_count >= 8 { return; }
5925
5926 let hub = &global_usb_hubs[usb_hub_count as usize];
5927 (*hub).address = device_addr;
5928 (*hub).is_active = true;
5929
5930 let desc_buf = pmm_alloc_blocks(1) as ptr<UsbHubDescriptor>;
5931
5932 let mut setup: [u8; 8];
5933 setup[0] = 0xA0;
5934 setup[1] = 0x06;
5935 setup[2] = 0x00;
5936 setup[3] = 0x29;
5937 setup[4] = 0x00;
5938 setup[5] = 0x00;
5939 setup[6] = sizeof(UsbHubDescriptor) as u8;
5940 setup[7] = 0x00;
5941
5942 (*hub).num_ports = (*desc_buf).num_ports;
5943 if (*hub).num_ports > 16 { (*hub).num_ports = 16; }
5944
5945 for p in 0..(*hub).num_ports {
5946 (*hub).ports[p as usize].port_id = p + 1;
5947 (*hub).ports[p as usize].is_connected = false;
5948
5949 setup[0] = 0x23;
5950 setup[1] = 0x03;
5951 setup[2] = 8;
5952 setup[3] = 0;
5953 setup[4] = p + 1;
5954 setup[5] = 0;
5955 setup[6] = 0;
5956 setup[7] = 0;
5957 }
5958
5959 usb_hub_count = usb_hub_count + 1;
5960 pmm_free_blocks(desc_buf as u64, 1);
5961 }
5962 fn usb_hub_poll_ports() {
5963 for i in 0..usb_hub_count {
5964 let hub = &global_usb_hubs[i as usize];
5965 if (*hub).is_active {
5966 for p in 0..(*hub).num_ports {
5967
5968 let mut setup: [u8; 8];
5969 setup[0] = 0xA3;
5970 setup[1] = 0x00;
5971 setup[2] = 0x00;
5972 setup[3] = 0x00;
5973 setup[4] = (*hub).ports[p as usize].port_id;
5974 setup[5] = 0x00;
5975 setup[6] = 0x04;
5976 setup[7] = 0x00;
5977
5978 let mut status: u32 = 0;
5979
5980 let connected = (status & 0x0001) != 0;
5981 let connect_change = (status & 0x10000) != 0;
5982
5983 if connect_change {
5984
5985 setup[0] = 0x23; setup[1] = 0x01; setup[2] = 16; setup[4] = (*hub).ports[p as usize].port_id;
5986
5987 if connected && !(*hub).ports[p as usize].is_connected {
5988
5989 setup[0] = 0x23; setup[1] = 0x03; setup[2] = 4; setup[4] = (*hub).ports[p as usize].port_id;
5990 (*hub).ports[p as usize].is_connected = true;
5991 } else if !connected && (*hub).ports[p as usize].is_connected {
5992 (*hub).ports[p as usize].is_connected = false;
5993 (*hub).ports[p as usize].device_address = 0;
5994 }
5995 }
5996 }
5997 }
5998 }
5999 }
6000 const SHADER_OP_NOP: u8 = 0;
6001 const SHADER_OP_MOV: u8 = 1;
6002 const SHADER_OP_ADD: u8 = 2;
6003 const SHADER_OP_MUL: u8 = 3;
6004 const SHADER_OP_DOT3: u8 = 4;
6005 const SHADER_OP_TEX: u8 = 5;
6006 const SHADER_OP_END: u8 = 255;
6007 struct ShaderInstruction {
6008 opcode: u8,
6009 dest_reg: u8,
6010 src1_reg: u8,
6011 src2_reg: u8,
6012 }
6013 struct GpuEuProgram {
6014 instructions: ptr<u32>,
6015 inst_count: u32,
6016 }
6017 fn gpu_shader_compile(shader_src: ptr<ShaderInstruction>, count: u32) -> ptr<GpuEuProgram> {
6018 let prog = pmm_alloc_blocks(1) as ptr<GpuEuProgram>;
6019 let max_native_inst = count * 4;
6020 (*prog).instructions = pmm_alloc_blocks((max_native_inst * 4 / PAGE_SIZE as u32) + 1) as ptr<u32>;
6021 (*prog).inst_count = 0;
6022
6023 for i in 0..count {
6024 let inst = (shader_src as u64 + i as u64 * sizeof(ShaderInstruction) as u64) as ptr<ShaderInstruction>;
6025 let op = (*inst).opcode;
6026 let dst = (*inst).dest_reg;
6027 let s1 = (*inst).src1_reg;
6028 let s2 = (*inst).src2_reg;
6029
6030 let out_ptr = ((*prog).instructions as u64 + (*prog).inst_count as u64 * 4) as ptr<u32>;
6031
6032 if op == SHADER_OP_ADD {
6033 *out_ptr = 0x40000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6034 (*prog).inst_count = (*prog).inst_count + 1;
6035 } else if op == SHADER_OP_MUL {
6036 *out_ptr = 0x41000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6037 (*prog).inst_count = (*prog).inst_count + 1;
6038 } else if op == SHADER_OP_DOT3 {
6039 *out_ptr = 0x42000000 | ((dst as u32) << 16) | ((s1 as u32) << 8) | (s2 as u32);
6040 (*prog).inst_count = (*prog).inst_count + 1;
6041 } else if op == SHADER_OP_END {
6042 *out_ptr = 0xFFFFFFFF;
6043 (*prog).inst_count = (*prog).inst_count + 1;
6044 break;
6045 }
6046 }
6047 return prog;
6048 }
6049 fn gpu_shader_bind(prog: ptr<GpuEuProgram>) {
6050 let phys_addr = (*prog).instructions as u64;
6051 intel_gpu_submit_cmd(0x71000000);
6052 intel_gpu_submit_cmd((phys_addr & 0xFFFFFFFF) as u32);
6053 intel_gpu_submit_cmd((phys_addr >> 32) as u32);
6054 intel_gpu_submit_cmd((*prog).inst_count * 4);
6055 }
6056 fn chainload_mbr(drive_num: u8, partition_lba: u64) {
6057 let boot_sector = 0x7C00 as ptr<u8>;
6058
6059 ahci_read_sectors(global_raid_sys.disks[0].ahci_port, partition_lba, 1, boot_sector as u64);
6060
6061 let signature = *(0x7DFE as ptr<u16>);
6062 if signature != 0xAA55 {
6063 shell_print_string("Chainload failed: Invalid MBR signature.\n" as ptr<u8>);
6064 return;
6065 }
6066
6067 cpu_cli();
6068
6069 asm {
6070 "mov edx, %0\n"
6071 "jmp 0x0000:0x7C00"
6072 in "%0" = drive_num as u32;
6073 }
6074 }
6075 struct Tpm2CrbControlArea {
6076 req: u32,
6077 sts: u32,
6078 cancel: u32,
6079 start: u32,
6080 int_ctrl: u64,
6081 cmd_size: u32,
6082 cmd_addr_low: u32,
6083 cmd_addr_high: u32,
6084 rsp_size: u32,
6085 rsp_addr_low: u32,
6086 rsp_addr_high: u32,
6087 }
6088 struct Tpm2CmdHeader {
6089 tag: u16,
6090 param_size: u32,
6091 cmd_code: u32,
6092 }
6093 let mut tpm2_crb_base: u64 = 0;
6094 let mut tpm2_ctrl_area: ptr<Tpm2CrbControlArea>;
6095 let mut tpm2_cmd_buf: ptr<u8>;
6096 let mut tpm2_rsp_buf: ptr<u8>;
6097 fn tpm2_init(acpi_tpm2_base: u64) {
6098 tpm2_crb_base = acpi_tpm2_base;
6099 tpm2_ctrl_area = (tpm2_crb_base + 0x40) as ptr<Tpm2CrbControlArea>;
6100
6101 (*tpm2_ctrl_area).req = 1;
6102 while ((*tpm2_ctrl_area).sts & 1) == 0 { cpu_pause(); }
6103
6104 tpm2_cmd_buf = ((((*tpm2_ctrl_area).cmd_addr_high as u64) << 32) | (*tpm2_ctrl_area).cmd_addr_low as u64) as ptr<u8>;
6105 tpm2_rsp_buf = ((((*tpm2_ctrl_area).rsp_addr_high as u64) << 32) | (*tpm2_ctrl_area).rsp_addr_low as u64) as ptr<u8>;
6106 }
6107 fn tpm2_send_command(cmd: ptr<u8>, size: u32) -> bool {
6108 memcpy(tpm2_cmd_buf, cmd, size as u64);
6109 (*tpm2_ctrl_area).start = 1;
6110
6111 let mut timeout = 1000000;
6112 while (*tpm2_ctrl_area).start != 0 && timeout > 0 {
6113 cpu_pause();
6114 timeout = timeout - 1;
6115 }
6116 return timeout > 0;
6117 }
6118 fn tpm2_get_random(bytes: u16, out_buf: ptr<u8>) -> bool {
6119 let mut cmd: [u8; 12];
6120 let hdr = &cmd[0] as ptr<Tpm2CmdHeader>;
6121 (*hdr).tag = htons(0x8001);
6122 (*hdr).param_size = htonl(12);
6123 (*hdr).cmd_code = htonl(0x0000017B);
6124 cmd[10] = (bytes >> 8) as u8;
6125 cmd[11] = (bytes & 0xFF) as u8;
6126
6127 if !tpm2_send_command(&cmd[0] as ptr<u8>, 12) { return false; }
6128
6129 let rsp_tag = htons(*(tpm2_rsp_buf as ptr<u16>));
6130 let rsp_code = htonl(*((tpm2_rsp_buf as u64 + 6) as ptr<u32>));
6131 if rsp_code != 0 { return false; }
6132
6133 let out_size = htons(*((tpm2_rsp_buf as u64 + 10) as ptr<u16>));
6134 memcpy(out_buf, (tpm2_rsp_buf as u64 + 12) as ptr<u8>, out_size as u64);
6135 return true;
6136 }
6137 fn rotl32(v: u32, c: u32) -> u32 { return (v << c) | (v >> (32 - c)); }
6138 struct ChaCha20Ctx {
6139 state: [u32; 16],
6140 }
6141 fn chacha20_init(ctx: ptr<ChaCha20Ctx>, key: ptr<u8>, nonce: ptr<u8>, counter: u32) {
6142 (*ctx).state[0] = 0x61707865;
6143 (*ctx).state[1] = 0x3320646e;
6144 (*ctx).state[2] = 0x79622d32;
6145 (*ctx).state[3] = 0x6b206574;
6146 for i in 0..8 {
6147 (*ctx).state[4 + i] = *((key as u64 + i as u64 * 4) as ptr<u32>);
6148 }
6149 (*ctx).state[12] = counter;
6150 for i in 0..3 {
6151 (*ctx).state[13 + i] = *((nonce as u64 + i as u64 * 4) as ptr<u32>);
6152 }
6153 }
6154 fn chacha20_quarter_round(state: ptr<u32>, a: usize, b: usize, c: usize, d: usize) {
6155 let s = state;
6156 *(s.offset(a as isize)) = *(s.offset(a as isize)) + *(s.offset(b as isize)); *(s.offset(d as isize)) = rotl32(*(s.offset(d as isize)) ^ *(s.offset(a as isize)), 16);
6157 *(s.offset(c as isize)) = *(s.offset(c as isize)) + *(s.offset(d as isize)); *(s.offset(b as isize)) = rotl32(*(s.offset(b as isize)) ^ *(s.offset(c as isize)), 12);
6158 *(s.offset(a as isize)) = *(s.offset(a as isize)) + *(s.offset(b as isize)); *(s.offset(d as isize)) = rotl32(*(s.offset(d as isize)) ^ *(s.offset(a as isize)), 8);
6159 *(s.offset(c as isize)) = *(s.offset(c as isize)) + *(s.offset(d as isize)); *(s.offset(b as isize)) = rotl32(*(s.offset(b as isize)) ^ *(s.offset(c as isize)), 7);
6160 }
6161 fn chacha20_block(ctx: ptr<ChaCha20Ctx>, out: ptr<u32>) {
6162 let mut working_state: [u32; 16];
6163 for i in 0..16 { working_state[i] = (*ctx).state[i]; }
6164
6165 for _ in 0..10 {
6166 chacha20_quarter_round(&working_state[0] as ptr<u32>, 0, 4, 8, 12);
6167 chacha20_quarter_round(&working_state[0] as ptr<u32>, 1, 5, 9, 13);
6168 chacha20_quarter_round(&working_state[0] as ptr<u32>, 2, 6, 10, 14);
6169 chacha20_quarter_round(&working_state[0] as ptr<u32>, 3, 7, 11, 15);
6170 chacha20_quarter_round(&working_state[0] as ptr<u32>, 0, 5, 10, 15);
6171 chacha20_quarter_round(&working_state[0] as ptr<u32>, 1, 6, 11, 12);
6172 chacha20_quarter_round(&working_state[0] as ptr<u32>, 2, 7, 8, 13);
6173 chacha20_quarter_round(&working_state[0] as ptr<u32>, 3, 4, 9, 14);
6174 }
6175
6176 for i in 0..16 { *(out as u64 + i as u64 * 4) as ptr<u32> = (*ctx).state[i] + working_state[i]; }
6177 (*ctx).state[12] = (*ctx).state[12] + 1;
6178 }
6179 fn chacha20_encrypt(ctx: ptr<ChaCha20Ctx>, data: ptr<u8>, len: u64) {
6180 let mut i: u64 = 0;
6181 let mut block: [u32; 16];
6182 while i < len {
6183 chacha20_block(ctx, &block[0] as ptr<u32>);
6184 let block_u8 = &block[0] as ptr<u32> as ptr<u8>;
6185 let mut chunk = 64;
6186 if len - i < 64 { chunk = len - i; }
6187 for j in 0..chunk {
6188 *(data as u64 + i + j) = *(data as u64 + i + j) ^ *(block_u8 as u64 + j);
6189 }
6190 i = i + 64;
6191 }
6192 }
6193 struct AvSignature {
6194 id: u32,
6195 name: [u8; 32],
6196 pattern: [u8; 16],
6197 pattern_len: u64,
6198 is_active: bool,
6199 }
6200 let mut global_av_signatures: [AvSignature; 1024];
6201 let mut av_sig_count: u32 = 0;
6202 fn av_init() {
6203 for i in 0..1024 { global_av_signatures[i].is_active = false; }
6204 }
6205 fn av_add_signature(name: ptr<u8>, pattern: ptr<u8>, len: u64) {
6206 if av_sig_count >= 1024 { return; }
6207 let sig = &global_av_signatures[av_sig_count as usize];
6208 (*sig).id = av_sig_count;
6209 strcpy(&((*sig).name[0]) as ptr<u8>, name);
6210 memcpy(&((*sig).pattern[0]) as ptr<u8>, pattern, len);
6211 (*sig).pattern_len = len;
6212 (*sig).is_active = true;
6213 av_sig_count = av_sig_count + 1;
6214 }
6215 fn av_scan_memory_region(start_addr: u64, length: u64) -> ptr<AvSignature> {
6216 let data = start_addr as ptr<u8>;
6217 for i in 0..av_sig_count {
6218 let sig = &global_av_signatures[i as usize];
6219 if (*sig).is_active {
6220 for j in 0..(length - (*sig).pattern_len) {
6221 let mut is_match = true;
6222 for k in 0..(*sig).pattern_len {
6223 if *(data as u64 + j + k) != (*sig).pattern[k as usize] {
6224 is_match = false;
6225 break;
6226 }
6227 }
6228 if is_match { return sig; }
6229 }
6230 }
6231 }
6232 return 0 as ptr<AvSignature>;
6233 }
6234 fn av_monitor_process(pid: u64) {
6235 let mut curr = process_queue;
6236 while curr != 0 as ptr<ProcessControlBlock> {
6237 if (*curr).pid == pid {
6238 let proc_map = (curr as u64 + sizeof(ProcessControlBlockExt) as u64) as ptr<ProcessMemoryMap>;
6239 let mut vma = (*proc_map).vma_head;
6240 while vma != 0 as ptr<VmaNode> {
6241 if ((*vma).flags & 4) != 0 {
6242 let sig = av_scan_memory_region((*vma).start_vaddr, (*vma).end_vaddr - (*vma).start_vaddr);
6243 if sig != 0 as ptr<AvSignature> {
6244 shell_print_string("AEGIS-AV ALERT: Malicious code detected! PID: " as ptr<u8>);
6245 let mut buf: [u8; 16]; itoa(pid as i32, 10, &buf[0] as ptr<u8>);
6246 shell_print_string(&buf[0] as ptr<u8>);
6247 shell_print_string(" Threat: " as ptr<u8>);
6248 shell_print_string(&((*sig).name[0]) as ptr<u8>);
6249 shell_print_char(10);
6250 signal_send(pid, SIGKILL);
6251 return;
6252 }
6253 }
6254 vma = (*vma).next;
6255 }
6256 break;
6257 }
6258 curr = (*curr).next;
6259 }
6260 }
6261 struct CowBlock {
6262 logical_block: u64,
6263 physical_block: u64,
6264 ref_count: u32,
6265 next: ptr<CowBlock>,
6266 }
6267 struct CowSnapshot {
6268 snap_id: u32,
6269 timestamp: u64,
6270 blocks: ptr<CowBlock>,
6271 next: ptr<CowSnapshot>,
6272 }
6273 let mut global_cow_mapping: ptr<CowBlock>;
6274 let mut global_snapshots: ptr<CowSnapshot>;
6275 let mut cow_next_snap_id: u32 = 1;
6276 fn cow_init() {
6277 global_cow_mapping = 0 as ptr<CowBlock>;
6278 global_snapshots = 0 as ptr<CowSnapshot>;
6279 }
6280 fn cow_get_physical(logical: u64) -> u64 {
6281 let mut curr = global_cow_mapping;
6282 while curr != 0 as ptr<CowBlock> {
6283 if (*curr).logical_block == logical { return (*curr).physical_block; }
6284 curr = (*curr).next;
6285 }
6286 return logical;
6287 }
6288 fn cow_write_block(logical: u64, data_buf: u64) {
6289 let mut curr = global_cow_mapping;
6290 let mut target_node = 0 as ptr<CowBlock>;
6291
6292 while curr != 0 as ptr<CowBlock> {
6293 if (*curr).logical_block == logical { target_node = curr; break; }
6294 curr = (*curr).next;
6295 }
6296
6297 if target_node != 0 as ptr<CowBlock> && (*target_node).ref_count > 1 {
6298 (*target_node).ref_count = (*target_node).ref_count - 1;
6299 let new_phys = swap_alloc_slot() + 2000000;
6300
6301 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
6302 memset(new_node as ptr<u8>, 0, sizeof(CowBlock) as u64);
6303 (*new_node).logical_block = logical;
6304 (*new_node).physical_block = new_phys;
6305 (*new_node).ref_count = 1;
6306 (*new_node).next = global_cow_mapping;
6307 global_cow_mapping = new_node;
6308
6309 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, new_phys, 8, data_buf);
6310 } else if target_node != 0 as ptr<CowBlock> {
6311 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, (*target_node).physical_block, 8, data_buf);
6312 } else {
6313 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
6314 memset(new_node as ptr<u8>, 0, sizeof(CowBlock) as u64);
6315 (*new_node).logical_block = logical;
6316 (*new_node).physical_block = logical;
6317 (*new_node).ref_count = 1;
6318 (*new_node).next = global_cow_mapping;
6319 global_cow_mapping = new_node;
6320 ahci_write_sectors(global_raid_sys.disks[0].ahci_port, logical, 8, data_buf);
6321 }
6322 }
6323 fn cow_create_snapshot() -> u32 {
6324 let snap = pmm_alloc_blocks(1) as ptr<CowSnapshot>;
6325 memset(snap as ptr<u8>, 0, sizeof(CowSnapshot) as u64);
6326 (*snap).snap_id = cow_next_snap_id;
6327 cow_next_snap_id = cow_next_snap_id + 1;
6328 (*snap).timestamp = current_time_tick;
6329
6330 let mut curr_block = global_cow_mapping;
6331 while curr_block != 0 as ptr<CowBlock> {
6332 (*curr_block).ref_count = (*curr_block).ref_count + 1;
6333
6334 let copy_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
6335 memcpy(copy_node as ptr<u8>, curr_block as ptr<u8>, sizeof(CowBlock) as u64);
6336 (*copy_node).next = (*snap).blocks;
6337 (*snap).blocks = copy_node;
6338
6339 curr_block = (*curr_block).next;
6340 }
6341
6342 (*snap).next = global_snapshots;
6343 global_snapshots = snap;
6344 return (*snap).snap_id;
6345 }
6346 fn cow_rollback_snapshot(snap_id: u32) -> bool {
6347 let mut snap = global_snapshots;
6348 while snap != 0 as ptr<CowSnapshot> {
6349 if (*snap).snap_id == snap_id {
6350 let mut old_mapping = global_cow_mapping;
6351 while old_mapping != 0 as ptr<CowBlock> {
6352 let next = (*old_mapping).next;
6353 pmm_free_blocks(old_mapping as u64, 1);
6354 old_mapping = next;
6355 }
6356
6357 global_cow_mapping = 0 as ptr<CowBlock>;
6358 let mut snap_block = (*snap).blocks;
6359 while snap_block != 0 as ptr<CowBlock> {
6360 let new_node = pmm_alloc_blocks(1) as ptr<CowBlock>;
6361 memcpy(new_node as ptr<u8>, snap_block as ptr<u8>, sizeof(CowBlock) as u64);
6362 (*new_node).next = global_cow_mapping;
6363 global_cow_mapping = new_node;
6364 snap_block = (*snap_block).next;
6365 }
6366 return true;
6367 }
6368 snap = (*snap).next;
6369 }
6370 return false;
6371 }
6372 struct FacsHeader {
6373 signature: [u8; 4],
6374 length: u32,
6375 hardware_signature: u32,
6376 firmware_waking_vector: u32,
6377 global_lock: u32,
6378 flags: u32,
6379 x_firmware_waking_vector: u64,
6380 version: u8,
6381 reserved: [u8; 3],
6382 ospm_flags: u32,
6383 }
6384 fn acpi_enter_s3_sleep() {
6385 if acpi_fadt == 0 as ptr<FADTHeader> { return; }
6386 let facs = (*acpi_fadt).firmware_ctrl as u64 as ptr<FacsHeader>;
6387
6388 (*facs).firmware_waking_vector = 0x8000;
6389
6390 let pm1a = (*acpi_fadt).pm1a_control_block;
6391 let pm1b = (*acpi_fadt).pm1b_control_block;
6392
6393 let slp_typ_a = 5;
6394 let slp_en = 1 << 13;
6395
6396 if pm1a != 0 { outw(pm1a as u16, (slp_typ_a << 10) | slp_en); }
6397 if pm1b != 0 { outw(pm1b as u16, (slp_typ_a << 10) | slp_en); }
6398
6399 cpu_cli();
6400 loop { cpu_hlt(); }
6401 }
6402 struct TlsRecordHeader {
6403 content_type: u8,
6404 version_major: u8,
6405 version_minor: u8,
6406 length: u16,
6407 }
6408 struct TlsHandshakeHeader {
6409 msg_type: u8,
6410 length: [u8; 3],
6411 }
6412 const TLS_TYPE_CHANGE_CIPHER_SPEC: u8 = 20;
6413 const TLS_TYPE_ALERT: u8 = 21;
6414 const TLS_TYPE_HANDSHAKE: u8 = 22;
6415 const TLS_TYPE_APPLICATION_DATA: u8 = 23;
6416 const TLS_HS_CLIENT_HELLO: u8 = 1;
6417 const TLS_HS_SERVER_HELLO: u8 = 2;
6418 const TLS_HS_CERTIFICATE: u8 = 11;
6419 const TLS_HS_SERVER_KEY_EXCHANGE: u8 = 12;
6420 const TLS_HS_SERVER_HELLO_DONE: u8 = 14;
6421 const TLS_HS_CLIENT_KEY_EXCHANGE: u8 = 16;
6422 const TLS_HS_FINISHED: u8 = 20;
6423 struct TlsSession {
6424 sock: ptr<TcpSocket>,
6425 master_secret: [u8; 48],
6426 client_random: [u8; 32],
6427 server_random: [u8; 32],
6428 is_handshake_complete: bool,
6429 cipher_suite: u16,
6430 tx_sequence: u64,
6431 rx_sequence: u64,
6432 }
6433 let mut global_tls_sessions: [TlsSession; 128];
6434 let mut tls_session_count: u32 = 0;
6435 fn tls_init() {
6436 for i in 0..128 {
6437 global_tls_sessions[i].is_handshake_complete = false;
6438 global_tls_sessions[i].tx_sequence = 0;
6439 global_tls_sessions[i].rx_sequence = 0;
6440 }
6441 }
6442 fn tls_send_client_hello(session: ptr<TlsSession>) {
6443 let buf = pmm_alloc_blocks(1) as ptr<u8>;
6444 let rec = buf as ptr<TlsRecordHeader>;
6445 (*rec).content_type = TLS_TYPE_HANDSHAKE;
6446 (*rec).version_major = 3;
6447 (*rec).version_minor = 3;
6448
6449 let hs = (buf as u64 + sizeof(TlsRecordHeader) as u64) as ptr<TlsHandshakeHeader>;
6450 (*hs).msg_type = TLS_HS_CLIENT_HELLO;
6451
6452 let hello_data = (buf as u64 + sizeof(TlsRecordHeader) as u64 + sizeof(TlsHandshakeHeader) as u64) as ptr<u8>;
6453 *(hello_data) = 3; *(hello_data as u64 + 1) as ptr<u8> = 3;
6454
6455 for i in 0..32 {
6456 (*session).client_random[i] = (rand_next() & 0xFF) as u8;
6457 *(hello_data as u64 + 2 + i as u64) as ptr<u8> = (*session).client_random[i];
6458 }
6459
6460 *(hello_data as u64 + 34) as ptr<u8> = 0;
6461
6462 *(hello_data as u64 + 35) as ptr<u16> = htons(4);
6463 *(hello_data as u64 + 37) as ptr<u16> = htons(0xC02F);
6464 *(hello_data as u64 + 39) as ptr<u16> = htons(0xC02B);
6465
6466 *(hello_data as u64 + 41) as ptr<u8> = 1;
6467 *(hello_data as u64 + 42) as ptr<u8> = 0;
6468
6469 let hs_len = 43;
6470 (*hs).length[0] = 0;
6471 (*hs).length[1] = (hs_len >> 8) as u8;
6472 (*hs).length[2] = (hs_len & 0xFF) as u8;
6473
6474 (*rec).length = htons(sizeof(TlsHandshakeHeader) as u16 + hs_len as u16);
6475
6476 tcp_send_data((*session).sock, buf, sizeof(TlsRecordHeader) as u32 + sizeof(TlsHandshakeHeader) as u32 + hs_len);
6477 pmm_free_blocks(buf as u64, 1);
6478 }
6479 fn tls_connect(sock: ptr<TcpSocket>) -> ptr<TlsSession> {
6480 if tls_session_count >= 128 { return 0 as ptr<TlsSession>; }
6481 let session = &global_tls_sessions[tls_session_count as usize];
6482 tls_session_count = tls_session_count + 1;
6483
6484 (*session).sock = sock;
6485 (*session).is_handshake_complete = false;
6486 tls_send_client_hello(session);
6487
6488 return session;
6489 }
6490 struct LivePatchHeader {
6491 magic: u32,
6492 patch_version: u32,
6493 num_funcs: u32,
6494 }
6495 struct LivePatchFunc {
6496 old_addr: u64,
6497 new_addr: u64,
6498 size: u32,
6499 }
6500 fn livepatch_apply(patch_data: ptr<u8>) -> bool {
6501 let hdr = patch_data as ptr<LivePatchHeader>;
6502 if (*hdr).magic != 0x4B4C5058 { return false; }
6503
6504 let funcs = (patch_data as u64 + sizeof(LivePatchHeader) as u64) as ptr<LivePatchFunc>;
6505
6506 cpu_cli();
6507
6508 let cr0 = rdmsr(0);
6509 asm { "mov rax, cr0\n and rax, 0xFFFEFFFF\n mov cr0, rax" }
6510
6511 for i in 0..(*hdr).num_funcs {
6512 let f = (funcs as u64 + i as u64 * sizeof(LivePatchFunc) as u64) as ptr<LivePatchFunc>;
6513 let target = (*f).old_addr as ptr<u8>;
6514 let dest = (*f).new_addr;
6515
6516 *target = 0xE9;
6517 let rel_offset = (dest as i64 - ((*f).old_addr as i64 + 5)) as i32;
6518 *((target as u64 + 1) as ptr<i32>) = rel_offset;
6519 }
6520
6521 asm { "mov rax, cr0\n or rax, 0x00010000\n mov cr0, rax" }
6522
6523 cpu_sti();
6524 return true;
6525 }
6526 fn rsod_dump_registers(ctx: ptr<CpuContext>) {
6527 comp_draw_rect(comp_root_window, 0, 0, comp_width, comp_height, 0xAA0000);
6528
6529 let mut y = 50;
6530 (*global_shell).win = comp_root_window;
6531 (*global_shell).fg_color = 0xFFFFFF;
6532
6533 shell_print_string("====================================================\n" as ptr<u8>);
6534 shell_print_string(" AEGIS-X KERNEL PANIC - RED SCREEN OF DEATH \n" as ptr<u8>);
6535 shell_print_string("====================================================\n" as ptr<u8>);
6536 shell_print_string("A critical system error has occurred. System halted.\n\n" as ptr<u8>);
6537
6538 let mut buf: [u8; 32];
6539 shell_print_string("RIP: 0x" as ptr<u8>); itoa((*ctx).rip as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
6540 shell_print_string("RAX: 0x" as ptr<u8>); itoa((*ctx).rax as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
6541 shell_print_string("RBX: 0x" as ptr<u8>); itoa((*ctx).rbx as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
6542 shell_print_string("RCX: 0x" as ptr<u8>); itoa((*ctx).rcx as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
6543 shell_print_string("RDX: 0x" as ptr<u8>); itoa((*ctx).rdx as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
6544 shell_print_string("RSI: 0x" as ptr<u8>); itoa((*ctx).rsi as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
6545 shell_print_string("RDI: 0x" as ptr<u8>); itoa((*ctx).rdi as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
6546 shell_print_string("RSP: 0x" as ptr<u8>); itoa((*ctx).rsp as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(" " as ptr<u8>);
6547 shell_print_string("RBP: 0x" as ptr<u8>); itoa((*ctx).rbp as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n\n" as ptr<u8>);
6548
6549 let cr2: u64; asm { "mov %0, cr2" out cr2 = cr2; }
6550 shell_print_string("CR2 (Fault Addr): 0x" as ptr<u8>); itoa(cr2 as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
6551
6552 shell_print_string("\nStack Trace:\n" as ptr<u8>);
6553 let mut rbp_ptr = (*ctx).rbp as ptr<u64>;
6554 for i in 0..8 {
6555 if rbp_ptr as u64 == 0 { break; }
6556 let ret_addr = *(rbp_ptr as u64 + 8) as ptr<u64>;
6557 shell_print_string("[<0x" as ptr<u8>); itoa(*ret_addr as i32, 16, &buf[0] as ptr<u8>); shell_print_string(&buf[0] as ptr<u8>); shell_print_string(">]\n" as ptr<u8>);
6558 rbp_ptr = *rbp_ptr as ptr<u64>;
6559 }
6560
6561 shell_print_string("\nPlease restart your computer. (System Halted)" as ptr<u8>);
6562 }
6563 fn kernel_panic(ctx: ptr<CpuContext>) -> ! {
6564 cpu_cli();
6565 rsod_dump_registers(ctx);
6566 loop { cpu_hlt(); }
6567 }
6568 fn exc_page_fault(ctx: ptr<CpuContext>) {
6569 let cr2: u64; asm { "mov %0, cr2" out cr2 = cr2; }
6570 let err_code = (*ctx).r15;
6571
6572 let is_handled = false;
6573
6574 if !is_handled {
6575 kernel_panic(ctx);
6576 }
6577 }
6578 fn syscall_handler_master() {
6579 let mut rax: u64; let mut rdi: u64; let mut rsi: u64;
6580 let mut rdx: u64; let mut r10: u64; let mut r8: u64; let mut r9: u64;
6581
6582 asm { "mov %0, rax" out rax = rax; }
6583 asm { "mov %0, rdi" out rdi = rdi; }
6584 asm { "mov %0, rsi" out rsi = rsi; }
6585 asm { "mov %0, rdx" out rdx = rdx; }
6586 asm { "mov %0, r10" out r10 = r10; }
6587 asm { "mov %0, r8" out r8 = r8; }
6588 asm { "mov %0, r9" out r9 = r9; }
6589 if rax == 0 { asm { "mov rax, %0" in rax = sys_read_wrap(rdi, rsi, rdx); } }
6590 else if rax == 1 { asm { "mov rax, %0" in rax = sys_write_wrap(rdi, rsi, rdx); } }
6591 else if rax == 2 { asm { "mov rax, %0" in rax = sys_open_wrap(rdi, rsi); } }
6592 else if rax == 3 { pmm_free_blocks(rdi, 1); asm { "mov rax, 0" } }
6593 else if rax == 9 { asm { "mov rax, %0" in rax = sys_mmap(rdi, rsi, rdx, r10, r8, r9); } }
6594 else if rax == 59 { asm { "mov rax, %0" in rax = execve_ring3(rdi as ptr<u8>, rsi as u32, rdx as u32); } }
6595 else if rax == 60 { (*current_process).state = 0; scheduler_tick(); }
6596 else if rax == 100 { comp_draw_rect(rdi as ptr<CompositorWindow>, rsi as u32, rdx as u32, r10 as u32, r8 as u32, r9 as u32); asm { "mov rax, 0" } }
6597 else if rax == 101 { gui_draw_string(rdi as ptr<CompositorWindow>, rsi as ptr<u8>, rdx as u32, r10 as u32, r8 as u32, r9 as u32); asm { "mov rax, 0" } }
6598 else if rax == 200 { sha256_init(rdi as ptr<Sha256Ctx>); sha256_transform(rdi as ptr<Sha256Ctx>, rsi as ptr<u8>); asm { "mov rax, 0" } }
6599 else if rax == 300 { asm { "mov rax, %0" in rax = ipc_send_message(rdi, rsi, rdx as u32, r10 as ptr<u8>, r8 as u32) as u64; } }
6600 else if rax == 301 { asm { "mov rax, %0" in rax = ipc_receive_message(rdi, rsi as ptr<IpcMessage>) as u64; } }
6601 else if rax == 400 { asm { "mov rax, %0" in rax = tcp_create_socket() as u64; } }
6602 else if rax == 401 { tcp_connect(rdi as ptr<TcpSocket>, *(rsi as ptr<Ipv4Addr>), rdx as u16); asm { "mov rax, 0" } }
6603 else if rax == 402 { tcp_send_data(rdi as ptr<TcpSocket>, rsi as ptr<u8>, rdx as u32); asm { "mov rax, 0" } }
6604 else if rax == 500 { asm { "mov rax, %0" in rax = shm_create(rdi as u32, rsi, rdx as u32, r10) as u64; } }
6605 else if rax == 501 { asm { "mov rax, %0" in rax = shm_attach(rdi, rsi, rdx) as u64; } }
6606 else if rax == 600 { asm { "mov rax, %0" in rax = ptrace_attach(rdi, rsi) as u64; } }
6607 else if rax == 700 { asm { "mov rax, %0" in rax = display_srv_create_surface(rdi) as u64; } }
6608 else if rax == 800 { asm { "mov rax, %0" in rax = tensor_create(rdi as u32, rsi as u32) as u64; } }
6609 else { asm { "mov rax, -1" } }
6610 }
6611 const MULTIBOOT_MAGIC: u32 = 0x2BADB002;
6612 struct MultibootInfo {
6613 flags: u32,
6614 mem_lower: u32,
6615 mem_upper: u32,
6616 boot_device: u32,
6617 cmdline: u32,
6618 mods_count: u32,
6619 mods_addr: u32,
6620 syms: [u32; 4],
6621 mmap_length: u32,
6622 mmap_addr: u32,
6623 drives_length: u32,
6624 drives_addr: u32,
6625 config_table: u32,
6626 boot_loader_name: u32,
6627 apm_table: u32,
6628 vbe_control_info: u32,
6629 vbe_mode_info: u32,
6630 vbe_mode: u16,
6631 vbe_interface_seg: u16,
6632 vbe_interface_off: u16,
6633 vbe_interface_len: u16,
6634 framebuffer_addr: u64,
6635 framebuffer_pitch: u32,
6636 framebuffer_width: u32,
6637 framebuffer_height: u32,
6638 framebuffer_bpp: u8,
6639 framebuffer_type: u8,
6640 }
6641 #[no_mangle]
6642 pub fn kmain(magic: u32, mb_info: ptr<MultibootInfo>) -> ! {
6643 cpu_cli();
6644
6645 if magic != MULTIBOOT_MAGIC {
6646 loop { cpu_hlt(); }
6647 }
6648
6649 init_gdt_smp();
6650 init_idt_smp();
6651
6652 let total_mem_kb = (*mb_info).mem_lower + (*mb_info).mem_upper;
6653 pmm_init(total_mem_kb as u64);
6654
6655 vmm_init();
6656
6657 acpi_init();
6658
6659 smp_init_all();
6660 smp_balancer_init();
6661
6662 let w = (*mb_info).framebuffer_width;
6663 let h = (*mb_info).framebuffer_height;
6664 let fb_base = (*mb_info).framebuffer_addr;
6665 comp_init(fb_base, w, h);
6666 vt_init();
6667 render_init_3d(w, h);
6668
6669 pcie_init();
6670
6671 if global_ahci_hba != 0 as ptr<AHCIHBARegs> {
6672 raid_init_system();
6673 for i in 0..32 {
6674 let port = &((*global_ahci_hba).ports[i as usize]) as ptr<AHCIPortRegs>;
6675 if ((*port).ssts & 0x0F) == 3 {
6676 raid_add_disk(port, 100000000);
6677 }
6678 }
6679 }
6680
6681 vfs_init_system();
6682 if global_raid_sys.disk_count > 0 {
6683 ext2_init(0);
6684 jbd2_init(2000000, 2100000);
6685 }
6686 cow_init();
6687
6688 if (*mb_info).mods_count > 0 {
6689 let mod_addr = (*mb_info).mods_addr as ptr<u32>;
6690 let initramfs_start = *mod_addr;
6691 let initramfs_end = *(mod_addr as u64 + 4) as ptr<u32>;
6692 tar_extract_initramfs(initramfs_start as u64, (*initramfs_end - initramfs_start) as u64);
6693 }
6694
6695 loopback_init();
6696 fw_init();
6697 nat_init();
6698 tls_init();
6699
6700 auth_init_system();
6701 registry_init();
6702 db_init();
6703 av_init();
6704
6705 pmu_init();
6706 acpi_update_battery_state();
6707
6708 vmx_init();
6709
6710 let shell_pid = execve_ring3("/bin/aegis_shell" as ptr<u8>, 0, 0);
6711 if shell_pid == 0 {
6712 let proc = create_process(shell_task as u64, true);
6713 }
6714
6715 let http_proc = create_process(http_server_task as u64, true);
6716
6717 init_set_runlevel(3);
6718
6719 cpu_sti();
6720
6721 loop {
6722 scheduler_tick();
6723 smp_balance_load();
6724 display_srv_composite();
6725 usb_hub_poll_ports();
6726 cpu_pause();
6727 }
6728 }
6729 struct YbgTransaction {
6730 sender_pubkey: [u8; 64],
6731 receiver_pubkey: [u8; 64],
6732 amount: u64,
6733 signature: [u8; 64],
6734 timestamp: u64,
6735 }
6736 struct YbgBlockHeader {
6737 index: u64,
6738 prev_hash: [u8; 32],
6739 merkle_root: [u8; 32],
6740 timestamp: u64,
6741 difficulty: u32,
6742 nonce: u64,
6743 }
6744 struct YbgBlock {
6745 header: YbgBlockHeader,
6746 transactions: ptr<YbgTransaction>,
6747 tx_count: u32,
6748 block_hash: [u8; 32],
6749 next: ptr<YbgBlock>,
6750 }
6751 let mut blockchain_head: ptr<YbgBlock>;
6752 let mut current_difficulty: u32 = 4;
6753 fn ybg_chain_init() {
6754 blockchain_head = pmm_alloc_blocks(1) as ptr<YbgBlock>;
6755 memset(blockchain_head as ptr<u8>, 0, sizeof(YbgBlock) as u64);
6756 (*blockchain_head).header.index = 0;
6757 strcpy(&((*blockchain_head).header.prev_hash[0]) as ptr<u8>, "YBG13_GENESIS_BLOCK_00000000000" as ptr<u8>);
6758 (*blockchain_head).header.timestamp = current_time_tick;
6759 (*blockchain_head).header.difficulty = current_difficulty;
6760 (*blockchain_head).header.nonce = 0;
6761 (*blockchain_head).tx_count = 0;
6762 }
6763 fn ybg_check_hash_difficulty(hash: ptr<u8>, difficulty: u32) -> bool {
6764 let mut zero_count = 0;
6765 for i in 0..32 {
6766 let byte = *(hash as u64 + i as u64) as ptr<u8>;
6767 if *byte == 0 {
6768 zero_count = zero_count + 2;
6769 } else if (*byte & 0xF0) == 0 {
6770 zero_count = zero_count + 1;
6771 break;
6772 } else {
6773 break;
6774 }
6775 if zero_count >= difficulty { return true; }
6776 }
6777 return zero_count >= difficulty;
6778 }
6779 fn ybg_mine_block(target_block: ptr<YbgBlock>) {
6780 let mut attempt_hash: [u8; 32];
6781 let mut ctx: Sha256Ctx;
6782
6783 shell_print_string("CHT-Miner: YBG13 Token kazimi basladi...\n" as ptr<u8>);
6784
6785 loop {
6786 sha256_init(&ctx);
6787 sha256_transform(&ctx, &((*target_block).header) as ptr<YbgBlockHeader> as ptr<u8>);
6788
6789 let state_ptr = &ctx.state[0] as ptr<u32> as ptr<u8>;
6790 for i in 0..32 { attempt_hash[i] = *(state_ptr + i); }
6791
6792 if ybg_check_hash_difficulty(&attempt_hash[0] as ptr<u8>, (*target_block).header.difficulty) {
6793 for i in 0..32 { (*target_block).block_hash[i] = attempt_hash[i]; }
6794 shell_print_string("CHT-Miner: Blok Bulundu! Nonce: " as ptr<u8>);
6795 let mut buf: [u8; 32]; itoa((*target_block).header.nonce as i32, 10, &buf[0] as ptr<u8>);
6796 shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
6797 break;
6798 }
6799
6800 (*target_block).header.nonce = (*target_block).header.nonce + 1;
6801 if ((*target_block).header.nonce % 10000) == 0 { scheduler_tick(); }
6802 }
6803 }
6804 struct ChtScanTarget {
6805 ip: Ipv4Addr,
6806 port_start: u16,
6807 port_end: u16,
6808 open_ports: [u16; 1024],
6809 open_count: u32,
6810 }
6811 fn cht_stealth_syn_scan(target: ptr<ChtScanTarget>) {
6812 shell_print_string("CHT-Sec: Stealth SYN Scan baslatiliyor...\n" as ptr<u8>);
6813
6814 let sock = tcp_create_socket();
6815 if sock == 0 as ptr<TcpSocket> { return; }
6816
6817 (*target).open_count = 0;
6818
6819 for port in (*target).port_start..=(*target).port_end {
6820 tcp_bind(sock, 45000 + (port % 10000));
6821 (*sock).remote_ip = (*target).ip;
6822 (*sock).remote_port = port;
6823 (*sock).seq_num = hw_rdrand_64() as u32;
6824
6825 tcp_send_segment(sock, 0x0002, 0 as ptr<u8>, 0);
6826
6827 let mut timeout = 5000;
6828 let mut port_open = false;
6829
6830 while timeout > 0 {
6831 if (*sock).state == TCP_STATE_SYN_RCVD || (*sock).state == TCP_STATE_ESTABLISHED {
6832 port_open = true;
6833 break;
6834 }
6835 if (*sock).state == TCP_STATE_CLOSED { break; }
6836 timeout = timeout - 1;
6837 cpu_pause();
6838 }
6839
6840 if port_open {
6841 if (*target).open_count < 1024 {
6842 (*target).open_ports[(*target).open_count as usize] = port;
6843 (*target).open_count = (*target).open_count + 1;
6844
6845 shell_print_string("CHT-Sec: Port Acik -> " as ptr<u8>);
6846 let mut pbuf: [u8; 16]; itoa(port as i32, 10, &pbuf[0] as ptr<u8>);
6847 shell_print_string(&pbuf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
6848 }
6849 tcp_send_segment(sock, 0x0004, 0 as ptr<u8>, 0);
6850 }
6851
6852 (*sock).state = TCP_STATE_CLOSED;
6853 (*sock).rx_head = 0; (*sock).rx_tail = 0;
6854 }
6855
6856 global_tcp_sockets[(*sock).id as usize - 1].is_active = false;
6857 shell_print_string("CHT-Sec: Tarama Tamamlandi.\n" as ptr<u8>);
6858 }
6859 struct UavTelemetryPacket {
6860 magic: u32,
6861 device_id: u8,
6862 timestamp: u64,
6863 accel_x: f32,
6864 accel_y: f32,
6865 accel_z: f32,
6866 gyro_x: f32,
6867 gyro_y: f32,
6868 gyro_z: f32,
6869 depth_pressure: f32,
6870 motor_rpm: [u16; 4],
6871 battery_voltage: f32,
6872 checksum: u16,
6873 }
6874 let mut uav_last_telemetry: UavTelemetryPacket;
6875 fn uav_parse_telemetry(udp_payload: ptr<u8>, length: u32) {
6876 if length != sizeof(UavTelemetryPacket) as u32 { return; }
6877
6878 let pkt = udp_payload as ptr<UavTelemetryPacket>;
6879 if (*pkt).magic != 0x414E4B41 { return; } // 'ANKA'
6880
6881 let mut csum: u32 = 0;
6882 let ptr16 = udp_payload as ptr<u16>;
6883 for i in 0..((length - 2) / 2) {
6884 csum = csum + *(ptr16 as u64 + i as u64 * 2) as ptr<u16> as u32;
6885 }
6886 while (csum >> 16) != 0 { csum = (csum & 0xFFFF) + (csum >> 16); }
6887 let calc_csum = (!csum) as u16;
6888
6889 if calc_csum == (*pkt).checksum {
6890 memcpy(&uav_last_telemetry as ptr<UavTelemetryPacket> as ptr<u8>, udp_payload, length as u64);
6891 }
6892 }
6893 const TK_EOF: u8 = 0;
6894 const TK_IDENTIFIER: u8 = 1;
6895 const TK_NUMBER: u8 = 2;
6896 const TK_PLUS: u8 = 3;
6897 const TK_MINUS: u8 = 4;
6898 const TK_ASSIGN: u8 = 5;
6899 const TK_PRINT: u8 = 6;
6900 const TK_SEMI: u8 = 7;
6901 struct ScriptToken {
6902 type_: u8,
6903 value_int: i64,
6904 name: [u8; 32],
6905 }
6906 struct ScriptLexer {
6907 src: ptr<u8>,
6908 pos: u32,
6909 len: u32,
6910 }
6911 fn script_is_alpha(c: u8) -> bool { return (c >= 'a' as u8 && c <= 'z' as u8) || (c >= 'A' as u8 && c <= 'Z' as u8) || c == '_' as u8; }
6912 fn script_is_digit(c: u8) -> bool { return c >= '0' as u8 && c <= '9' as u8; }
6913 fn script_next_token(lex: ptr<ScriptLexer>, out_tok: ptr<ScriptToken>) {
6914 while (*lex).pos < (*lex).len {
6915 let c = *((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>;
6916 if c == ' ' as u8 || c == 10 || c == 13 || c == 9 {
6917 (*lex).pos = (*lex).pos + 1;
6918 continue;
6919 }
6920
6921 if script_is_digit(c) {
6922 (*out_tok).type_ = TK_NUMBER;
6923 (*out_tok).value_int = 0;
6924 while (*lex).pos < (*lex).len && script_is_digit(*((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>) {
6925 (*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;
6926 (*lex).pos = (*lex).pos + 1;
6927 }
6928 return;
6929 }
6930
6931 if script_is_alpha(c) {
6932 let mut i = 0;
6933 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 {
6934 (*out_tok).name[i] = *((*lex).src as u64 + (*lex).pos as u64) as ptr<u8>;
6935 (*lex).pos = (*lex).pos + 1;
6936 i = i + 1;
6937 }
6938 (*out_tok).name[i] = 0;
6939
6940 if strcmp(&((*out_tok).name[0]) as ptr<u8>, "print" as ptr<u8>) == 0 {
6941 (*out_tok).type_ = TK_PRINT;
6942 } else {
6943 (*out_tok).type_ = TK_IDENTIFIER;
6944 }
6945 return;
6946 }
6947
6948 if c == '+' as u8 { (*out_tok).type_ = TK_PLUS; (*lex).pos = (*lex).pos + 1; return; }
6949 if c == '-' as u8 { (*out_tok).type_ = TK_MINUS; (*lex).pos = (*lex).pos + 1; return; }
6950 if c == '=' as u8 { (*out_tok).type_ = TK_ASSIGN; (*lex).pos = (*lex).pos + 1; return; }
6951 if c == ';' as u8 { (*out_tok).type_ = TK_SEMI; (*lex).pos = (*lex).pos + 1; return; }
6952
6953 (*lex).pos = (*lex).pos + 1;
6954 }
6955 (*out_tok).type_ = TK_EOF;
6956 }
6957 struct ScriptVar {
6958 name: [u8; 32],
6959 value: i64,
6960 is_active: bool,
6961 }
6962 let mut global_script_env: [ScriptVar; 64];
6963 fn script_set_var(name: ptr<u8>, val: i64) {
6964 for i in 0..64 {
6965 if global_script_env[i].is_active && strcmp(&(global_script_env[i].name[0]) as ptr<u8>, name) == 0 {
6966 global_script_env[i].value = val;
6967 return;
6968 }
6969 }
6970 for i in 0..64 {
6971 if !global_script_env[i].is_active {
6972 strcpy(&(global_script_env[i].name[0]) as ptr<u8>, name);
6973 global_script_env[i].value = val;
6974 global_script_env[i].is_active = true;
6975 return;
6976 }
6977 }
6978 }
6979 fn script_get_var(name: ptr<u8>) -> i64 {
6980 for i in 0..64 {
6981 if global_script_env[i].is_active && strcmp(&(global_script_env[i].name[0]) as ptr<u8>, name) == 0 {
6982 return global_script_env[i].value;
6983 }
6984 }
6985 return 0;
6986 }
6987 fn aegis_script_run(source_code: ptr<u8>) {
6988 let mut lex: ScriptLexer;
6989 lex.src = source_code;
6990 lex.pos = 0;
6991 lex.len = strlen(source_code) as u32;
6992
6993 for i in 0..64 { global_script_env[i].is_active = false; }
6994
6995 let mut tok: ScriptToken;
6996 script_next_token(&mut lex, &mut tok);
6997
6998 while tok.type_ != TK_EOF {
6999 if tok.type_ == TK_IDENTIFIER {
7000 let var_name = tok.name;
7001 script_next_token(&mut lex, &mut tok);
7002 if tok.type_ == TK_ASSIGN {
7003 script_next_token(&mut lex, &mut tok);
7004 let mut val: i64 = 0;
7005 if tok.type_ == TK_NUMBER { val = tok.value_int; }
7006 else if tok.type_ == TK_IDENTIFIER { val = script_get_var(&tok.name[0] as ptr<u8>); }
7007 script_set_var(&var_name[0] as ptr<u8>, val);
7008 script_next_token(&mut lex, &mut tok);
7009 }
7010 } else if tok.type_ == TK_PRINT {
7011 script_next_token(&mut lex, &mut tok);
7012 let mut val: i64 = 0;
7013 if tok.type_ == TK_NUMBER { val = tok.value_int; }
7014 else if tok.type_ == TK_IDENTIFIER { val = script_get_var(&tok.name[0] as ptr<u8>); }
7015
7016 shell_print_string("Aegis-Script Out: " as ptr<u8>);
7017 let mut buf: [u8; 32]; itoa(val as i32, 10, &buf[0] as ptr<u8>);
7018 shell_print_string(&buf[0] as ptr<u8>); shell_print_string("\n" as ptr<u8>);
7019 script_next_token(&mut lex, &mut tok);
7020 } else {
7021 script_next_token(&mut lex, &mut tok);
7022 }
7023 }
7024 }
7025 const MB_MAGIC: u32 = 0x1BADB002;
7026 const MB_FLAGS: u32 = 0x00000003;
7027 const MB_CKSUM: u32 = -(MB_MAGIC + MB_FLAGS);
7028 struct Multiboot { magic: u32, flags: u32, checksum: u32 }
7029 const HEADER: Multiboot = Multiboot { magic: MB_MAGIC, flags: MB_FLAGS, checksum: MB_CKSUM };
7030 fn outb(p: u16, d: u8) { asm { "out dx, al" in dx = p; in al = d; } }
7031 fn outw(p: u16, d: u16) { asm { "out dx, ax" in dx = p; in ax = d; } }
7032 fn outl(p: u16, d: u32) { asm { "out dx, eax" in dx = p; in eax = d; } }
7033 fn inb(p: u16) -> u8 { let mut d: u8; asm { "in al, dx" in dx = p; out al = d; } return d; }
7034 fn inw(p: u16) -> u16 { let mut d: u16; asm { "in ax, dx" in dx = p; out ax = d; } return d; }
7035 fn inl(p: u16) -> u32 { let mut d: u32; asm { "in eax, dx" in dx = p; out eax = d; } return d; }
7036 struct CpuContext {
7037 r15: u64, r14: u64, r13: u64, r12: u64,
7038 r11: u64, r10: u64, r9: u64, r8: u64,
7039 rbp: u64, rdi: u64, rsi: u64, rdx: u64,
7040 rcx: u64, rbx: u64, rax: u64,
7041 rip: u64, cs: u64, rflags: u64, rsp: u64, ss: u64,
7042 }
7043 struct ProcessControlBlock {
7044 pid: u64,
7045 state: u8,
7046 cr3_phys: u64,
7047 context: ptr<CpuContext>,
7048 time_slice: u64,
7049 privilege_level: u8,
7050 next: ptr<ProcessControlBlock>,
7051 }
7052 let mut current_process: ptr<ProcessControlBlock> = 0 as ptr<ProcessControlBlock>;
7053 let mut process_queue: ptr<ProcessControlBlock> = 0 as ptr<ProcessControlBlock>;
7054 fn sched() {
7055 if current_process == 0 as ptr<ProcessControlBlock> { return; }
7056 let mut next_proc = (*current_process).next;
7057 if next_proc == 0 as ptr<ProcessControlBlock> {
7058 next_proc = process_queue;
7059 }
7060 while (*next_proc).state != 1 {
7061 next_proc = (*next_proc).next;
7062 if next_proc == 0 as ptr<ProcessControlBlock> { next_proc = process_queue; }
7063 }
7064 current_process = next_proc;
7065 }
7066 struct AegisCap {
7067 uid: u32,
7068 net_access: bool,
7069 fs_access: bool,
7070 hw_access: bool,
7071 }
7072 fn aegis_verify(proc: ptr<ProcessControlBlock>, req_cap: u8) -> bool {
7073 if (*proc).privilege_level == 0 { return true; }
7074 return false;
7075 }
7076 fn syscall_handler() {
7077 let mut eax: u32; let mut ebx: u32; let mut ecx: u32; let mut edx: u32;
7078 asm { "mov %0, eax" out eax = eax; }
7079 asm { "mov %0, ebx" out ebx = ebx; }
7080 asm { "mov %0, ecx" out ecx = ecx; }
7081 asm { "mov %0, edx" out edx = edx; }
7082
7083 if eax == 1 { asm { "mov eax, %0" in eax = kmalloc(ebx) as u32; } }
7084 else if eax == 2 { kfree(ebx as ptr<u8>); asm { "mov eax, 0" } }
7085 else if eax == 3 { wm_crt(ebx, ecx); asm { "mov eax, 0" } }
7086 else if eax == 4 { tcp_syn(0, ebx as u16, ecx as u16); asm { "mov eax, 0" } }
7087 else if eax == 5 { crypto_init(); asm { "mov eax, 0" } }
7088 else { asm { "mov eax, -1" } }
7089 }
7090 fn idle_t() { loop { cpu_hlt(); sched(); } }
7091 fn gui_t() { loop { wm_cmp(); sched(); } }
7092 fn net_t() { loop { arp_req(0); sched(); } }
7093 #[no_mangle]
7094 pub fn _start() -> ! {
7095 cpu_cli();
7096 init_gdt_smp();
7097 init_idt_smp();
7098 pmm_init();
7099 vmm_init();
7100 init_apic_smp();
7101
7102 crypto_init();
7103 vfs_init();
7104
7105 create_process(idle_t as u64, 0);
7106 create_process(gui_t as u64, 0);
7107 create_process(net_t as u64, 0);
7108
7109 cpu_sti();
7110 loop {
7111 sched();
7112 cpu_pause();
7113 }
7114 }
7115 const DRIVER_TYPE_NETWORK: u8 = 1;
7116 const DRIVER_TYPE_STORAGE: u8 = 2;
7117 const DRIVER_TYPE_DISPLAY: u8 = 3;
7118 const DRIVER_TYPE_AUDIO: u8 = 4;
7119 const DRIVER_TYPE_INPUT: u8 = 5;
7120 const DRIVER_TYPE_USB_HC: u8 = 6;
7121 struct DeviceDriver {
7122 name: [u8; 32],
7123 drv_type: u8,
7124 init_func: u64,
7125 read_func: u64,
7126 write_func: u64,
7127 irq_handler: u64,
7128 is_loaded: bool,
7129 }
7130 let mut global_driver_registry: [DeviceDriver; 1024];
7131 let mut registered_driver_count: u32 = 0;
7132 fn register_driver(name: ptr<u8>, d_type: u8, init: u64, read: u64, write: u64, irq: u64) {
7133 if registered_driver_count >= 1024 { return; }
7134 let drv = &global_driver_registry[registered_driver_count as usize];
7135 strcpy(&(drv.name[0]) as ptr<u8>, name);
7136 drv.drv_type = d_type;
7137 drv.init_func = init;
7138 drv.read_func = read;
7139 drv.write_func = write;
7140 drv.irq_handler = irq;
7141 drv.is_loaded = false;
7142 registered_driver_count = registered_driver_count + 1;
7143 }
7144 fn drv_e1000_init() -> bool { shell_print_string("Loading Intel PRO/1000...\n" as ptr<u8>); return true; }
7145 fn drv_e1000e_init() -> bool { shell_print_string("Loading Intel PCIe Gigabit...\n" as ptr<u8>); return true; }
7146 fn drv_ixgbe_init() -> bool { shell_print_string("Loading Intel 10GbE...\n" as ptr<u8>); return true; }
7147 fn drv_rtl8139_init() -> bool { shell_print_string("Loading Realtek 8139...\n" as ptr<u8>); return true; }
7148 fn drv_rtl8168_init() -> bool { shell_print_string("Loading Realtek 8168/8111...\n" as ptr<u8>); return true; }
7149 fn drv_virtio_net_init() -> bool { shell_print_string("Loading VirtIO Network...\n" as ptr<u8>); return true; }
7150 fn drv_broadcom_net_init() -> bool { shell_print_string("Loading Broadcom NetXtreme...\n" as ptr<u8>); return true; }
7151 fn drv_atheros_wifi_init() -> bool { shell_print_string("Loading Atheros 802.11...\n" as ptr<u8>); return true; }
7152 fn drv_intel_wifi_init() -> bool { shell_print_string("Loading Intel Wireless WiFi...\n" as ptr<u8>); return true; }
7153 fn drv_ahci_init() -> bool { shell_print_string("Loading AHCI SATA Controller...\n" as ptr<u8>); return true; }
7154 fn drv_nvme_init() -> bool { shell_print_string("Loading NVMe Controller...\n" as ptr<u8>); return true; }
7155 fn drv_ide_init() -> bool { shell_print_string("Loading Legacy IDE Controller...\n" as ptr<u8>); return true; }
7156 fn drv_virtio_blk_init() -> bool { shell_print_string("Loading VirtIO Block...\n" as ptr<u8>); return true; }
7157 fn drv_sdhci_init() -> bool { shell_print_string("Loading SD Host Controller...\n" as ptr<u8>); return true; }
7158 fn drv_lsi_sas_init() -> bool { shell_print_string("Loading LSI SAS Controller...\n" as ptr<u8>); return true; }
7159 fn drv_xhci_init() -> bool { shell_print_string("Loading USB 3.0 xHCI...\n" as ptr<u8>); return true; }
7160 fn drv_ehci_init() -> bool { shell_print_string("Loading USB 2.0 EHCI...\n" as ptr<u8>); return true; }
7161 fn drv_uhci_init() -> bool { shell_print_string("Loading USB 1.1 UHCI...\n" as ptr<u8>); return true; }
7162 fn drv_ohci_init() -> bool { shell_print_string("Loading USB 1.0 OHCI...\n" as ptr<u8>); return true; }
7163 fn drv_intel_gma_init() -> bool { shell_print_string("Loading Intel GMA/HD Graphics...\n" as ptr<u8>); return true; }
7164 fn drv_amd_radeon_init() -> bool { shell_print_string("Loading AMD Radeon Graphics...\n" as ptr<u8>); return true; }
7165 fn drv_nvidia_nouveau_init() -> bool { shell_print_string("Loading Nvidia (Nouveau) Graphics...\n" as ptr<u8>); return true; }
7166 fn drv_virtio_gpu_init() -> bool { shell_print_string("Loading VirtIO GPU...\n" as ptr<u8>); return true; }
7167 fn drv_vbox_video_init() -> bool { shell_print_string("Loading VirtualBox Video...\n" as ptr<u8>); return true; }
7168 fn drv_vmware_svga_init() -> bool { shell_print_string("Loading VMware SVGA II...\n" as ptr<u8>); return true; }
7169 fn drv_bochs_vbe_init() -> bool { shell_print_string("Loading Bochs VBE Display...\n" as ptr<u8>); return true; }
7170 fn drv_intel_hda_init() -> bool { shell_print_string("Loading Intel High Definition Audio...\n" as ptr<u8>); return true; }
7171 fn drv_ac97_init() -> bool { shell_print_string("Loading AC97 Audio...\n" as ptr<u8>); return true; }
7172 fn drv_sb16_init() -> bool { shell_print_string("Loading Sound Blaster 16...\n" as ptr<u8>); return true; }
7173 fn drv_ps2_kbd_init() -> bool { shell_print_string("Loading PS/2 Keyboard...\n" as ptr<u8>); return true; }
7174 fn drv_ps2_mouse_init() -> bool { shell_print_string("Loading PS/2 Mouse...\n" as ptr<u8>); return true; }
7175 fn drv_usb_hid_init() -> bool { shell_print_string("Loading USB HID (Kbd/Mouse)...\n" as ptr<u8>); return true; }
7176 fn drv_i2c_hid_init() -> bool { shell_print_string("Loading I2C HID Touchpad...\n" as ptr<u8>); return true; }
7177 fn uda_register_all_drivers() {
7178 register_driver("e1000" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_e1000_init as u64, 0, 0, 0);
7179 register_driver("e1000e" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_e1000e_init as u64, 0, 0, 0);
7180 register_driver("ixgbe" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_ixgbe_init as u64, 0, 0, 0);
7181 register_driver("rtl8139" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_rtl8139_init as u64, 0, 0, 0);
7182 register_driver("rtl8168" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_rtl8168_init as u64, 0, 0, 0);
7183 register_driver("virtio-net" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_virtio_net_init as u64, 0, 0, 0);
7184 register_driver("bcm-net" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_broadcom_net_init as u64, 0, 0, 0);
7185 register_driver("ath-wifi" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_atheros_wifi_init as u64, 0, 0, 0);
7186 register_driver("iwlwifi" as ptr<u8>, DRIVER_TYPE_NETWORK, drv_intel_wifi_init as u64, 0, 0, 0);
7187
7188 register_driver("ahci" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_ahci_init as u64, 0, 0, 0);
7189 register_driver("nvme" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_nvme_init as u64, 0, 0, 0);
7190 register_driver("ide" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_ide_init as u64, 0, 0, 0);
7191 register_driver("virtio-blk" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_virtio_blk_init as u64, 0, 0, 0);
7192 register_driver("sdhci" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_sdhci_init as u64, 0, 0, 0);
7193 register_driver("lsi-sas" as ptr<u8>, DRIVER_TYPE_STORAGE, drv_lsi_sas_init as u64, 0, 0, 0);
7194
7195 register_driver("xhci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_xhci_init as u64, 0, 0, 0);
7196 register_driver("ehci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_ehci_init as u64, 0, 0, 0);
7197 register_driver("uhci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_uhci_init as u64, 0, 0, 0);
7198 register_driver("ohci" as ptr<u8>, DRIVER_TYPE_USB_HC, drv_ohci_init as u64, 0, 0, 0);
7199
7200 register_driver("intel-gma" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_intel_gma_init as u64, 0, 0, 0);
7201 register_driver("amd-radeon" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_amd_radeon_init as u64, 0, 0, 0);
7202 register_driver("nvidia" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_nvidia_nouveau_init as u64, 0, 0, 0);
7203 register_driver("virtio-gpu" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_virtio_gpu_init as u64, 0, 0, 0);
7204 register_driver("vbox-video" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_vbox_video_init as u64, 0, 0, 0);
7205 register_driver("vmware-svga" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_vmware_svga_init as u64, 0, 0, 0);
7206 register_driver("bochs-vbe" as ptr<u8>, DRIVER_TYPE_DISPLAY, drv_bochs_vbe_init as u64, 0, 0, 0);
7207
7208 register_driver("intel-hda" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_intel_hda_init as u64, 0, 0, 0);
7209 register_driver("ac97" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_ac97_init as u64, 0, 0, 0);
7210 register_driver("sb16" as ptr<u8>, DRIVER_TYPE_AUDIO, drv_sb16_init as u64, 0, 0, 0);
7211
7212 register_driver("ps2-kbd" as ptr<u8>, DRIVER_TYPE_INPUT, drv_ps2_kbd_init as u64, 0, 0, 0);
7213 register_driver("ps2-mouse" as ptr<u8>, DRIVER_TYPE_INPUT, drv_ps2_mouse_init as u64, 0, 0, 0);
7214 register_driver("usb-hid" as ptr<u8>, DRIVER_TYPE_INPUT, drv_usb_hid_init as u64, 0, 0, 0);
7215 register_driver("i2c-hid" as ptr<u8>, DRIVER_TYPE_INPUT, drv_i2c_hid_init as u64, 0, 0, 0);
7216 }
7217 fn get_pci_vendor_name(vendor_id: u16) -> ptr<u8> {
7218 if vendor_id == 0x8086 { return "Intel Corporation" as ptr<u8>; }
7219 if vendor_id == 0x1002 { return "Advanced Micro Devices (AMD)" as ptr<u8>; }
7220 if vendor_id == 0x10DE { return "NVIDIA Corporation" as ptr<u8>; }
7221 if vendor_id == 0x10EC { return "Realtek Semiconductor Co., Ltd." as ptr<u8>; }
7222 if vendor_id == 0x14E4 { return "Broadcom Inc. and subsidiaries" as ptr<u8>; }
7223 if vendor_id == 0x1AF4 { return "Red Hat, Inc. (Virtio)" as ptr<u8>; }
7224 if vendor_id == 0x15AD { return "VMware" as ptr<u8>; }
7225 if vendor_id == 0x80EE { return "InnoTek Systemberatung GmbH (VirtualBox)" as ptr<u8>; }
7226 if vendor_id == 0x1022 { return "AMD (Legacy)" as ptr<u8>; }
7227 if vendor_id == 0x104C { return "Texas Instruments" as ptr<u8>; }
7228 if vendor_id == 0x11AB { return "Marvell Technology Group Ltd." as ptr<u8>; }
7229 if vendor_id == 0x197B { return "JMicron Technology Corp." as ptr<u8>; }
7230 if vendor_id == 0x1014 { return "IBM" as ptr<u8>; }
7231 if vendor_id == 0x0E11 { return "Compaq Computer Corporation" as ptr<u8>; }
7232 if vendor_id == 0x103C { return "Hewlett-Packard Company" as ptr<u8>; }
7233 if vendor_id == 0x1028 { return "Dell" as ptr<u8>; }
7234 if vendor_id == 0x1043 { return "ASUSTeK Computer Inc." as ptr<u8>; }
7235 if vendor_id == 0x1458 { return "Gigabyte Technology Co., Ltd" as ptr<u8>; }
7236 if vendor_id == 0x1462 { return "Micro-Star International Co., Ltd. [MSI]" as ptr<u8>; }
7237 if vendor_id == 0x15B3 { return "Mellanox Technologies" as ptr<u8>; }
7238 if vendor_id == 0x1B36 { return "Red Hat, Inc. (QEMU)" as ptr<u8>; }
7239 if vendor_id == 0x1C58 { return "HGST, Inc." as ptr<u8>; }
7240 if vendor_id == 0x144D { return "Samsung Electronics Co Ltd" as ptr<u8>; }
7241 if vendor_id == 0x152D { return "JMicron Technology Corp. (NVMe)" as ptr<u8>; }
7242 if vendor_id == 0x1D0F { return "Amazon.com, Inc." as ptr<u8>; }
7243 if vendor_id == 0x1AE0 { return "Google, Inc." as ptr<u8>; }
7244 if vendor_id == 0x106B { return "Apple Inc." as ptr<u8>; }
7245 if vendor_id == 0x105A { return "Promise Technology, Inc." as ptr<u8>; }
7246 if vendor_id == 0x10B5 { return "PLX Technology, Inc." as ptr<u8>; }
7247 if vendor_id == 0x10DF { return "Emulex Corporation" as ptr<u8>; }
7248 if vendor_id == 0x1106 { return "VIA Technologies, Inc." as ptr<u8>; }
7249 if vendor_id == 0x1179 { return "Toshiba Corporation" as ptr<u8>; }
7250 if vendor_id == 0x1186 { return "D-Link System Inc" as ptr<u8>; }
7251 if vendor_id == 0x13F0 { return "Sundance Technology Inc / IC Plus Corp" as ptr<u8>; }
7252 if vendor_id == 0x168C { return "Qualcomm Atheros" as ptr<u8>; }
7253 if vendor_id == 0x1814 { return "Ralink corp." as ptr<u8>; }
7254 if vendor_id == 0x1B21 { return "ASMedia Technology Inc." as ptr<u8>; }
7255 if vendor_id == 0x8087 { return "Intel Corporation (Wireless)" as ptr<u8>; }
7256 return "Unknown Vendor" as ptr<u8>;
7257 }
7258 fn get_pci_device_name(vendor_id: u16, device_id: u16) -> ptr<u8> {
7259 // --- INTEL DEVICES ---
7260 if vendor_id == 0x8086 {
7261 if device_id == 0x100E { return "Gigabit Ethernet Controller (e1000)" as ptr<u8>; }
7262 if device_id == 0x100F { return "Gigabit Ethernet Controller (e1000)" as ptr<u8>; }
7263 if device_id == 0x10D3 { return "82574L Gigabit Network Connection" as ptr<u8>; }
7264 if device_id == 0x10EA { return "82577LM Gigabit Network Connection" as ptr<u8>; }
7265 if device_id == 0x1502 { return "82579LM Gigabit Network Connection" as ptr<u8>; }
7266 if device_id == 0x1503 { return "82579V Gigabit Network Connection" as ptr<u8>; }
7267 if device_id == 0x153A { return "I217-LM Gigabit Network Connection" as ptr<u8>; }
7268 if device_id == 0x153B { return "I217-V Gigabit Network Connection" as ptr<u8>; }
7269 if device_id == 0x15B7 { return "I219-LM Gigabit Network Connection" as ptr<u8>; }
7270 if device_id == 0x15B8 { return "I219-V Gigabit Network Connection" as ptr<u8>; }
7271 if device_id == 0x10FB { return "82599ES 10-Gigabit SFI/SFP+ Network Connection" as ptr<u8>; }
7272 if device_id == 0x1528 { return "Ethernet Controller 10-Gigabit X540-AT2" as ptr<u8>; }
7273 if device_id == 0x2922 { return "82801IR/IO/P (ICH9) 6 port SATA Controller [AHCI mode]" as ptr<u8>; }
7274 if device_id == 0x1C02 { return "6 Series/C200 Series Chipset Family 6 port SATA AHCI" as ptr<u8>; }
7275 if device_id == 0x1E02 { return "7 Series/C210 Series Chipset Family 6-port SATA Controller" as ptr<u8>; }
7276 if device_id == 0x8C02 { return "8 Series/C220 Series Chipset Family 6-port SATA Controller" as ptr<u8>; }
7277 if device_id == 0xA102 { return "100 Series/C230 Series Chipset Family SATA AHCI" as ptr<u8>; }
7278 if device_id == 0xA282 { return "200 Series/Z370 Chipset Family SATA AHCI Controller" as ptr<u8>; }
7279 if device_id == 0x0116 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
7280 if device_id == 0x0166 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
7281 if device_id == 0x0412 { return "4th Gen Core Processor Integrated Graphics Controller" as ptr<u8>; }
7282 if device_id == 0x1912 { return "HD Graphics 530" as ptr<u8>; }
7283 if device_id == 0x3E92 { return "UHD Graphics 630 (Desktop)" as ptr<u8>; }
7284 if device_id == 0x9BC5 { return "CometLake-S GT2 [UHD Graphics 630]" as ptr<u8>; }
7285 if device_id == 0x2668 { return "82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio" as ptr<u8>; }
7286 if device_id == 0x284B { return "82801H (ICH8 Family) High Definition Audio Controller" as ptr<u8>; }
7287 if device_id == 0x293E { return "82801I (ICH9 Family) High Definition Audio Controller" as ptr<u8>; }
7288 if device_id == 0x1E20 { return "7 Series/C210 Series Chipset Family High Definition Audio" as ptr<u8>; }
7289 if device_id == 0xA170 { return "100 Series/C230 Series Chipset Family HD Audio Controller" as ptr<u8>; }
7290 if device_id == 0x8C31 { return "8 Series/C220 Series Chipset Family USB xHCI" as ptr<u8>; }
7291 if device_id == 0xA12F { return "100 Series/C230 Series Chipset Family USB 3.0 xHCI" as ptr<u8>; }
7292 if device_id == 0x1E2D { return "7 Series/C210 Series Chipset Family USB Enhanced Host Controller" as ptr<u8>; }
7293 if device_id == 0x24C2 { return "82801DB/DBM (ICH4/ICH4-M) USB UHCI Controller" as ptr<u8>; }
7294 if device_id == 0xF1A5 { return "NVMe SSD Controller (Optane/760p)" as ptr<u8>; }
7295 if device_id == 0x4220 { return "PRO/Wireless 2200BG [Calexico2] Network Connection" as ptr<u8>; }
7296 if device_id == 0x4229 { return "PRO/Wireless 4965 AG or AGN [Kedron] Network Connection" as ptr<u8>; }
7297 if device_id == 0x0085 { return "Centrino Advanced-N 6205 [Taylor Peak]" as ptr<u8>; }
7298 if device_id == 0x08B1 { return "Wireless 7260" as ptr<u8>; }
7299 if device_id == 0x24FB { return "Dual Band Wireless-AC 3160" as ptr<u8>; }
7300 if device_id == 0x24FD { return "Dual Band Wireless-AC 8265" as ptr<u8>; }
7301 if device_id == 0x2723 { return "Wi-Fi 6 AX200" as ptr<u8>; }
7302 return "Intel Unknown Device" as ptr<u8>;
7303 }
7304
7305 // --- REALTEK DEVICES ---
7306 if vendor_id == 0x10EC {
7307 if device_id == 0x8139 { return "RTL-8100/8101L/8139 PCI Fast Ethernet Adapter" as ptr<u8>; }
7308 if device_id == 0x8168 { return "RTL8111/8168/8411 PCI Express Gigabit Ethernet" as ptr<u8>; }
7309 if device_id == 0x8169 { return "RTL8169 PCI Gigabit Ethernet Controller" as ptr<u8>; }
7310 if device_id == 0x8125 { return "RTL8125 2.5GbE Controller" as ptr<u8>; }
7311 if device_id == 0x818B { return "RTL8192EE PCIe Wireless Network Adapter" as ptr<u8>; }
7312 if device_id == 0x8821 { return "RTL8821AE 802.11ac PCIe Wireless Network Adapter" as ptr<u8>; }
7313 if device_id == 0x8822 { return "RTL8822BE 802.11a/b/g/n/ac WiFi adapter" as ptr<u8>; }
7314 if device_id == 0x522A { return "RTS522A PCI Express Card Reader" as ptr<u8>; }
7315 if device_id == 0x0282 { return "RTL8188EE Wireless Network Adapter" as ptr<u8>; }
7316 return "Realtek Unknown Device" as ptr<u8>;
7317 }
7318
7319 // --- NVIDIA DEVICES ---
7320 if vendor_id == 0x10DE {
7321 if device_id == 0x0402 { return "GeForce 8600 GT" as ptr<u8>; }
7322 if device_id == 0x0611 { return "GeForce 8800 GT" as ptr<u8>; }
7323 if device_id == 0x0A20 { return "GeForce GT 220" as ptr<u8>; }
7324 if device_id == 0x06C0 { return "GeForce GTX 480" as ptr<u8>; }
7325 if device_id == 0x1080 { return "GeForce GTX 580" as ptr<u8>; }
7326 if device_id == 0x1180 { return "GeForce GTX 680" as ptr<u8>; }
7327 if device_id == 0x13C2 { return "GeForce GTX 970" as ptr<u8>; }
7328 if device_id == 0x13C0 { return "GeForce GTX 980" as ptr<u8>; }
7329 if device_id == 0x1C03 { return "GeForce GTX 1060 6GB" as ptr<u8>; }
7330 if device_id == 0x1B81 { return "GeForce GTX 1070" as ptr<u8>; }
7331 if device_id == 0x1B06 { return "GeForce GTX 1080 Ti" as ptr<u8>; }
7332 if device_id == 0x1E84 { return "GeForce RTX 2070" as ptr<u8>; }
7333 if device_id == 0x1E07 { return "GeForce RTX 2080 Ti" as ptr<u8>; }
7334 if device_id == 0x2204 { return "GeForce RTX 3090" as ptr<u8>; }
7335 if device_id == 0x2484 { return "GeForce RTX 3070" as ptr<u8>; }
7336 if device_id == 0x2684 { return "GeForce RTX 4090" as ptr<u8>; }
7337 if device_id == 0x28E0 { return "GeForce RTX 4050 Laptop GPU" as ptr<u8>; } // YBG13's PC!
7338 if device_id == 0x0E0A { return "GF119 HDMI Audio Controller" as ptr<u8>; }
7339 if device_id == 0x0FB0 { return "GM200 High Definition Audio" as ptr<u8>; }
7340 if device_id == 0x10F0 { return "GP104 High Definition Audio Controller" as ptr<u8>; }
7341 if device_id == 0x10FA { return "TU104 HD Audio Controller" as ptr<u8>; }
7342 return "NVIDIA Unknown Device" as ptr<u8>;
7343 }
7344
7345 // --- AMD/ATI DEVICES ---
7346 if vendor_id == 0x1002 {
7347 if device_id == 0x6738 { return "Radeon HD 6870" as ptr<u8>; }
7348 if device_id == 0x6798 { return "Radeon HD 7970 / R9 280X" as ptr<u8>; }
7349 if device_id == 0x67B1 { return "Radeon R9 290 / 390" as ptr<u8>; }
7350 if device_id == 0x67DF { return "Radeon RX 470/480/570/580/590" as ptr<u8>; }
7351 if device_id == 0x687F { return "Radeon RX Vega 56/64" as ptr<u8>; }
7352 if device_id == 0x731F { return "Radeon RX 5700 XT" as ptr<u8>; }
7353 if device_id == 0x73BF { return "Radeon RX 6800 XT / 6900 XT" as ptr<u8>; }
7354 if device_id == 0x744C { return "Radeon RX 7900 XTX" as ptr<u8>; }
7355 if device_id == 0x4383 { return "SB7x0/SB8x0/SB9x0 High Definition Audio Controller" as ptr<u8>; }
7356 if device_id == 0x1457 { return "Family 17h (Models 00h-0fh) HD Audio Controller" as ptr<u8>; }
7357 if device_id == 0x4391 { return "SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode]" as ptr<u8>; }
7358 if device_id == 0x7901 { return "FCH SATA Controller [AHCI mode]" as ptr<u8>; }
7359 return "AMD/ATI Unknown Device" as ptr<u8>;
7360 }
7361
7362 // --- VIRTUALIZATION DEVICES (VIRTIO, VMWARE, VBOX) ---
7363 if vendor_id == 0x1AF4 {
7364 if device_id == 0x1000 { return "VirtIO Network Device" as ptr<u8>; }
7365 if device_id == 0x1001 { return "VirtIO Block Device" as ptr<u8>; }
7366 if device_id == 0x1002 { return "VirtIO Memory Balloon" as ptr<u8>; }
7367 if device_id == 0x1003 { return "VirtIO Console" as ptr<u8>; }
7368 if device_id == 0x1004 { return "VirtIO SCSI" as ptr<u8>; }
7369 if device_id == 0x1005 { return "VirtIO RNG" as ptr<u8>; }
7370 if device_id == 0x1041 { return "VirtIO Network Device (Modern)" as ptr<u8>; }
7371 if device_id == 0x1042 { return "VirtIO Block Device (Modern)" as ptr<u8>; }
7372 if device_id == 0x1050 { return "VirtIO GPU" as ptr<u8>; }
7373 return "VirtIO Unknown Device" as ptr<u8>;
7374 }
7375 if vendor_id == 0x15AD {
7376 if device_id == 0x0405 { return "VMware SVGA II Adapter" as ptr<u8>; }
7377 if device_id == 0x07B0 { return "VMware VMXNET3 Ethernet Controller" as ptr<u8>; }
7378 if device_id == 0x07A0 { return "VMware PVSCSI SCSI Controller" as ptr<u8>; }
7379 return "VMware Unknown Device" as ptr<u8>;
7380 }
7381 if vendor_id == 0x80EE {
7382 if device_id == 0xBEEF { return "VirtualBox Graphics Adapter" as ptr<u8>; }
7383 if device_id == 0xCAFE { return "VirtualBox Guest Service" as ptr<u8>; }
7384 return "VirtualBox Unknown Device" as ptr<u8>;
7385 }
7386
7387 // --- STORAGE/SAMSUNG/BROADCOM AND OTHERS ---
7388 if vendor_id == 0x144D {
7389 if device_id == 0xA802 { return "Samsung SM951 NVMe" as ptr<u8>; }
7390 if device_id == 0xA804 { return "Samsung 960 EVO/PRO NVMe" as ptr<u8>; }
7391 if device_id == 0xA808 { return "Samsung 970 EVO/PRO NVMe" as ptr<u8>; }
7392 if device_id == 0xA80A { return "Samsung 980 PRO NVMe" as ptr<u8>; }
7393 if device_id == 0xA80C { return "Samsung 990 PRO NVMe" as ptr<u8>; }
7394 return "Samsung NVMe Unknown" as ptr<u8>;
7395 }
7396 if vendor_id == 0x14E4 {
7397 if device_id == 0x1659 { return "NetXtreme BCM5721 Gigabit Ethernet" as ptr<u8>; }
7398 if device_id == 0x1677 { return "NetXtreme BCM5751 Gigabit Ethernet" as ptr<u8>; }
7399 if device_id == 0x4311 { return "BCM4311 802.11b/g WLAN" as ptr<u8>; }
7400 if device_id == 0x4322 { return "BCM4322 802.11a/b/g/n Wireless LAN" as ptr<u8>; }
7401 if device_id == 0x4360 { return "BCM4360 802.11ac Wireless Network Adapter" as ptr<u8>; }
7402 return "Broadcom Unknown Device" as ptr<u8>;
7403 }
7404 if vendor_id == 0x168C {
7405 if device_id == 0x002B { return "AR9285 Wireless Network Adapter" as ptr<u8>; }
7406 if device_id == 0x002E { return "AR9287 Wireless Network Adapter" as ptr<u8>; }
7407 if device_id == 0x0032 { return "AR9485 Wireless Network Adapter" as ptr<u8>; }
7408 if device_id == 0x003C { return "QCA986x/988x 802.11ac Wireless Network Adapter" as ptr<u8>; }
7409 return "Atheros Unknown Device" as ptr<u8>;
7410 }
7411 return "Generic Unknown PCI Device" as ptr<u8>;
7412 }
7413 struct PciDeviceInfo {
7414 bus: u8,
7415 slot: u8,
7416 func: u8,
7417 vendor_id: u16,
7418 device_id: u16,
7419 class_code: u8,
7420 subclass: u8,
7421 prog_if: u8,
7422 irq: u8,
7423 bar0: u32,
7424 bar1: u32,
7425 bar2: u32,
7426 bar3: u32,
7427 bar4: u32,
7428 bar5: u32,
7429 is_active: bool,
7430 }
7431 let mut pci_device_tree: [PciDeviceInfo; 256];
7432 let mut pci_device_count: u32 = 0;
7433 fn pci_config_read_word(bus: u8, slot: u8, func: u8, offset: u8) -> u16 {
7434 let address: u32 = ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32 & 0xFC) | 0x80000000;
7435 outl(0xCF8, address);
7436 let tmp = inl(0xCFC);
7437 return ((tmp >> ((offset & 2) * 8)) & 0xFFFF) as u16;
7438 }
7439 fn pci_config_read_dword(bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
7440 let address: u32 = ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32 & 0xFC) | 0x80000000;
7441 outl(0xCF8, address);
7442 return inl(0xCFC);
7443 }
7444 fn uda_probe_pci_bus() {
7445 shell_print_string("UDA: Probing PCI/PCIe Busses...\n" as ptr<u8>);
7446 for bus in 0..=255 {
7447 for slot in 0..32 {
7448 let vendor_id = pci_config_read_word(bus as u8, slot as u8, 0, 0);
7449 if vendor_id != 0xFFFF {
7450 let device_id = pci_config_read_word(bus as u8, slot as u8, 0, 2);
7451 let class_subclass = pci_config_read_word(bus as u8, slot as u8, 0, 0x0A);
7452 let class_code = (class_subclass >> 8) as u8;
7453 let subclass = (class_subclass & 0xFF) as u8;
7454 let prog_if = (pci_config_read_word(bus as u8, slot as u8, 0, 0x08) >> 8) as u8;
7455
7456 if pci_device_count < 256 {
7457 let dev = &pci_device_tree[pci_device_count as usize];
7458 dev.bus = bus as u8;
7459 dev.slot = slot as u8;
7460 dev.func = 0;
7461 dev.vendor_id = vendor_id;
7462 dev.device_id = device_id;
7463 dev.class_code = class_code;
7464 dev.subclass = subclass;
7465 dev.prog_if = prog_if;
7466 dev.is_active = true;
7467
7468 dev.bar0 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x10);
7469 dev.bar1 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x14);
7470 dev.bar2 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x18);
7471 dev.bar3 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x1C);
7472 dev.bar4 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x20);
7473 dev.bar5 = pci_config_read_dword(bus as u8, slot as u8, 0, 0x24);
7474 dev.irq = (pci_config_read_word(bus as u8, slot as u8, 0, 0x3C) & 0xFF) as u8;
7475
7476 pci_device_count = pci_device_count + 1;
7477
7478 uda_match_and_load_driver(dev);
7479 }
7480 }
7481 }
7482 }
7483 shell_print_string("UDA: PCI Scan Complete. Found devices: " as ptr<u8>);
7484 let mut buf: [u8; 16];
7485 itoa(pci_device_count as i32, 10, &buf[0] as ptr<u8>);
7486 shell_print_string(&buf[0] as ptr<u8>);
7487 shell_print_string("\n" as ptr<u8>);
7488 }
7489 fn uda_match_and_load_driver(dev: ptr<PciDeviceInfo>) {
7490 let vid = (*dev).vendor_id;
7491 let did = (*dev).device_id;
7492 let cls = (*dev).class_code;
7493 let sub = (*dev).subclass;
7494 let p_if = (*dev).prog_if;
7495 // --- Mass Storage Controllers ---
7496 if cls == 0x01 {
7497 if sub == 0x01 {
7498 drv_ide_init();
7499 } else if sub == 0x06 && p_if == 0x01 {
7500 drv_ahci_init();
7501 } else if sub == 0x08 && p_if == 0x02 {
7502 drv_nvme_init();
7503 }
7504 }
7505 else if cls == 0x02 {
7506 if sub == 0x00 { // Ethernet
7507 if vid == 0x8086 {
7508 if did == 0x100E || did == 0x100F { drv_e1000_init(); }
7509 else if did == 0x153A || did == 0x153B { drv_e1000e_init(); }
7510 else { drv_e1000e_init(); } // Generic fallback for intel network
7511 } else if vid == 0x10EC {
7512 if did == 0x8139 { drv_rtl8139_init(); }
7513 else if did == 0x8168 { drv_rtl8168_init(); }
7514 } else if vid == 0x1AF4 && did == 0x1000 {
7515 drv_virtio_net_init();
7516 }
7517 } else if sub == 0x80 { // Network controller (often WiFi)
7518 if vid == 0x8086 || vid == 0x8087 { drv_intel_wifi_init(); }
7519 else if vid == 0x168C { drv_atheros_wifi_init(); }
7520 }
7521 }
7522 else if cls == 0x03 {
7523 if vid == 0x8086 { drv_intel_gma_init(); }
7524 else if vid == 0x1002 { drv_amd_radeon_init(); }
7525 else if vid == 0x10DE { drv_nvidia_nouveau_init(); }
7526 else if vid == 0x15AD { drv_vmware_svga_init(); }
7527 else if vid == 0x80EE { drv_vbox_video_init(); }
7528 else if vid == 0x1AF4 { drv_virtio_gpu_init(); }
7529 else { drv_bochs_vbe_init(); }
7530 }
7531 else if cls == 0x04 {
7532 if sub == 0x01 { drv_ac97_init(); }
7533 else if sub == 0x03 { drv_intel_hda_init(); }
7534 }
7535 else if cls == 0x0C && sub == 0x03 {
7536 if p_if == 0x00 { drv_uhci_init(); }
7537 else if p_if == 0x10 { drv_ohci_init(); }
7538 else if p_if == 0x20 { drv_ehci_init(); }
7539 else if p_if == 0x30 { drv_xhci_init(); }
7540 }
7541 }
7542 fn uda_dump_device_tree() {
7543 shell_print_string("\n--- UDA DEVICE TREE DUMP ---\n" as ptr<u8>);
7544 for i in 0..pci_device_count {
7545 let dev = &pci_device_tree[i as usize];
7546 let v_name = get_pci_vendor_name(dev.vendor_id);
7547 let d_name = get_pci_device_name(dev.vendor_id, dev.device_id);
7548
7549 shell_print_string("BUS: " as ptr<u8>);
7550 let mut bbuf: [u8; 8]; itoa(dev.bus as i32, 10, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
7551
7552 shell_print_string(" | VID: 0x" as ptr<u8>);
7553 itoa(dev.vendor_id as i32, 16, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
7554
7555 shell_print_string(" | DID: 0x" as ptr<u8>);
7556 itoa(dev.device_id as i32, 16, &bbuf[0] as ptr<u8>); shell_print_string(&bbuf[0] as ptr<u8>);
7557
7558 shell_print_string("\n -> " as ptr<u8>);
7559 shell_print_string(v_name); shell_print_string(" - " as ptr<u8>); shell_print_string(d_name);
7560 shell_print_string("\n" as ptr<u8>);
7561 }
7562 shell_print_string("----------------------------\n" as ptr<u8>);
7563 }
7564 fn uda_thread() {
7565 uda_register_all_drivers();
7566 uda_probe_pci_bus();
7567 uda_dump_device_tree();
7568
7569 // UDA Daemon loop
7570 loop {
7571 // Here we would handle Hot-Plug events (PCIe Hotplug, USB Hotplug)
7572 cpu_pause();
7573 sched();
7574 }
7575 }
7576 fn drv_lsi_megaraid_init() -> bool { shell_print_string("Loading LSI MegaRAID SAS...\n" as ptr<u8>); return true; }
7577 fn drv_adaptec_raid_init() -> bool { shell_print_string("Loading Adaptec AACRAID...\n" as ptr<u8>); return true; }
7578 fn drv_promise_fasttrak_init() -> bool { shell_print_string("Loading Promise FastTrak RAID...\n" as ptr<u8>); return true; }
7579 fn drv_highpoint_rocketraid_init() -> bool { shell_print_string("Loading HighPoint RocketRAID...\n" as ptr<u8>); return true; }
7580 fn drv_via_sata_init() -> bool { shell_print_string("Loading VIA SATA Controller...\n" as ptr<u8>); return true; }
7581 fn drv_sis_sata_init() -> bool { shell_print_string("Loading SiS SATA Controller...\n" as ptr<u8>); return true; }
7582 fn drv_uli_sata_init() -> bool { shell_print_string("Loading ULi SATA Controller...\n" as ptr<u8>); return true; }
7583 fn drv_marvell_sata_init() -> bool { shell_print_string("Loading Marvell 88SE SATA...\n" as ptr<u8>); return true; }
7584 fn drv_jmicron_sata_init() -> bool { shell_print_string("Loading JMicron JMB36x SATA...\n" as ptr<u8>); return true; }
7585 fn drv_asmedia_sata_init() -> bool { shell_print_string("Loading ASMedia ASM106x SATA...\n" as ptr<u8>); return true; }
7586 fn drv_mellanox_cx_init() -> bool { shell_print_string("Loading Mellanox ConnectX 10/40/100GbE...\n" as ptr<u8>); return true; }
7587 fn drv_3com_3c905_init() -> bool { shell_print_string("Loading 3Com 3c905B Fast EtherLink...\n" as ptr<u8>); return true; }
7588 fn drv_dec_tulip_init() -> bool { shell_print_string("Loading DEC Tulip Ethernet...\n" as ptr<u8>); return true; }
7589 fn drv_sis_900_init() -> bool { shell_print_string("Loading SiS 900 PCI Fast Ethernet...\n" as ptr<u8>); return true; }
7590 fn drv_via_rhine_init() -> bool { shell_print_string("Loading VIA Rhine II Fast Ethernet...\n" as ptr<u8>); return true; }
7591 fn drv_via_velocity_init() -> bool { shell_print_string("Loading VIA Velocity Gigabit...\n" as ptr<u8>); return true; }
7592 fn drv_marvell_yukon_init() -> bool { shell_print_string("Loading Marvell Yukon Gigabit...\n" as ptr<u8>); return true; }
7593 fn drv_broadcom_tg3_init() -> bool { shell_print_string("Loading Broadcom Tigon3 Gigabit...\n" as ptr<u8>); return true; }
7594 fn drv_intel_10gbe_vf_init() -> bool { shell_print_string("Loading Intel 10GbE Virtual Function...\n" as ptr<u8>); return true; }
7595 fn drv_solarflare_init() -> bool { shell_print_string("Loading Solarflare 10/40GbE...\n" as ptr<u8>); return true; }
7596 fn drv_qlogic_net_init() -> bool { shell_print_string("Loading QLogic 10/25GbE...\n" as ptr<u8>); return true; }
7597 fn drv_matrox_g400_init() -> bool { shell_print_string("Loading Matrox G400/G450/G550...\n" as ptr<u8>); return true; }
7598 fn drv_3dfx_voodoo_init() -> bool { shell_print_string("Loading 3dfx Voodoo Graphics...\n" as ptr<u8>); return true; }
7599 fn drv_cirrus_logic_init() -> bool { shell_print_string("Loading Cirrus Logic GD5446...\n" as ptr<u8>); return true; }
7600 fn drv_s3_trio_init() -> bool { shell_print_string("Loading S3 Trio32/64...\n" as ptr<u8>); return true; }
7601 fn drv_s3_savage_init() -> bool { shell_print_string("Loading S3 Savage 3D...\n" as ptr<u8>); return true; }
7602 fn drv_via_chrome_init() -> bool { shell_print_string("Loading VIA UniChrome Graphics...\n" as ptr<u8>); return true; }
7603 fn drv_creative_emu10k1_init() -> bool { shell_print_string("Loading Creative Sound Blaster Live!...\n" as ptr<u8>); return true; }
7604 fn drv_creative_xifi_init() -> bool { shell_print_string("Loading Creative X-Fi Audio...\n" as ptr<u8>); return true; }
7605 fn drv_via_envy24_init() -> bool { shell_print_string("Loading VIA Envy24 Audio...\n" as ptr<u8>); return true; }
7606 fn drv_cmedia_cmi8738_init() -> bool { shell_print_string("Loading C-Media CMI8738 Audio...\n" as ptr<u8>); return true; }
7607 fn drv_cmedia_oxygen_init() -> bool { shell_print_string("Loading C-Media Oxygen HD Audio...\n" as ptr<u8>); return true; }
7608 fn drv_ess_solo1_init() -> bool { shell_print_string("Loading ESS Solo-1 Audio...\n" as ptr<u8>); return true; }
7609 fn drv_yamaha_ymf724_init() -> bool { shell_print_string("Loading Yamaha YMF724 Audio...\n" as ptr<u8>); return true; }
7610 fn drv_fresco_logic_xhci_init() -> bool { shell_print_string("Loading Fresco Logic xHCI USB 3.0...\n" as ptr<u8>); return true; }
7611 fn drv_renesas_xhci_init() -> bool { shell_print_string("Loading Renesas xHCI USB 3.0...\n" as ptr<u8>); return true; }
7612 fn drv_asmedia_xhci_init() -> bool { shell_print_string("Loading ASMedia xHCI USB 3.0/3.1...\n" as ptr<u8>); return true; }
7613 fn drv_via_xhci_init() -> bool { shell_print_string("Loading VIA xHCI USB 3.0...\n" as ptr<u8>); return true; }
7614 fn drv_ti_xhci_init() -> bool { shell_print_string("Loading Texas Instruments xHCI USB 3.0...\n" as ptr<u8>); return true; }
7615 fn drv_ti_firewire_init() -> bool { shell_print_string("Loading Texas Instruments IEEE 1394...\n" as ptr<u8>); return true; }
7616 fn drv_via_firewire_init() -> bool { shell_print_string("Loading VIA IEEE 1394 Firewire...\n" as ptr<u8>); return true; }
7617 fn drv_ricoh_firewire_init() -> bool { shell_print_string("Loading Ricoh IEEE 1394 Firewire...\n" as ptr<u8>); return true; }
7618 fn drv_ricoh_sd_init() -> bool { shell_print_string("Loading Ricoh SD/MMC Host Controller...\n" as ptr<u8>); return true; }
7619 fn drv_o2micro_sd_init() -> bool { shell_print_string("Loading O2Micro SD/MMC Host Controller...\n" as ptr<u8>); return true; }
7620 fn drv_ene_sd_init() -> bool { shell_print_string("Loading ENE Technology SD Host Controller...\n" as ptr<u8>); return true; }
7621 fn uda_register_extended_drivers() {
7622 register_driver("lsi_megaraid" as ptr<u8>, 2, drv_lsi_megaraid_init as u64, 0, 0, 0);
7623 register_driver("adaptec_raid" as ptr<u8>, 2, drv_adaptec_raid_init as u64, 0, 0, 0);
7624 register_driver("promise_raid" as ptr<u8>, 2, drv_promise_fasttrak_init as u64, 0, 0, 0);
7625 register_driver("highpoint_raid" as ptr<u8>, 2, drv_highpoint_rocketraid_init as u64, 0, 0, 0);
7626 register_driver("via_sata" as ptr<u8>, 2, drv_via_sata_init as u64, 0, 0, 0);
7627 register_driver("sis_sata" as ptr<u8>, 2, drv_sis_sata_init as u64, 0, 0, 0);
7628 register_driver("uli_sata" as ptr<u8>, 2, drv_uli_sata_init as u64, 0, 0, 0);
7629 register_driver("marvell_sata" as ptr<u8>, 2, drv_marvell_sata_init as u64, 0, 0, 0);
7630 register_driver("jmicron_sata" as ptr<u8>, 2, drv_jmicron_sata_init as u64, 0, 0, 0);
7631 register_driver("asmedia_sata" as ptr<u8>, 2, drv_asmedia_sata_init as u64, 0, 0, 0);
7632 register_driver("mellanox_cx" as ptr<u8>, 1, drv_mellanox_cx_init as u64, 0, 0, 0);
7633 register_driver("3com_3c905" as ptr<u8>, 1, drv_3com_3c905_init as u64, 0, 0, 0);
7634 register_driver("dec_tulip" as ptr<u8>, 1, drv_dec_tulip_init as u64, 0, 0, 0);
7635 register_driver("sis_900" as ptr<u8>, 1, drv_sis_900_init as u64, 0, 0, 0);
7636 register_driver("via_rhine" as ptr<u8>, 1, drv_via_rhine_init as u64, 0, 0, 0);
7637 register_driver("via_velocity" as ptr<u8>, 1, drv_via_velocity_init as u64, 0, 0, 0);
7638 register_driver("marvell_yukon" as ptr<u8>, 1, drv_marvell_yukon_init as u64, 0, 0, 0);
7639 register_driver("bcm_tg3" as ptr<u8>, 1, drv_broadcom_tg3_init as u64, 0, 0, 0);
7640 register_driver("intel_10gbe_vf" as ptr<u8>, 1, drv_intel_10gbe_vf_init as u64, 0, 0, 0);
7641 register_driver("solarflare" as ptr<u8>, 1, drv_solarflare_init as u64, 0, 0, 0);
7642 register_driver("qlogic_net" as ptr<u8>, 1, drv_qlogic_net_init as u64, 0, 0, 0);
7643 register_driver("matrox_g400" as ptr<u8>, 3, drv_matrox_g400_init as u64, 0, 0, 0);
7644 register_driver("3dfx_voodoo" as ptr<u8>, 3, drv_3dfx_voodoo_init as u64, 0, 0, 0);
7645 register_driver("cirrus_logic" as ptr<u8>, 3, drv_cirrus_logic_init as u64, 0, 0, 0);
7646 register_driver("s3_trio" as ptr<u8>, 3, drv_s3_trio_init as u64, 0, 0, 0);
7647 register_driver("s3_savage" as ptr<u8>, 3, drv_s3_savage_init as u64, 0, 0, 0);
7648 register_driver("via_chrome" as ptr<u8>, 3, drv_via_chrome_init as u64, 0, 0, 0);
7649 register_driver("sb_live" as ptr<u8>, 4, drv_creative_emu10k1_init as u64, 0, 0, 0);
7650 register_driver("sb_xifi" as ptr<u8>, 4, drv_creative_xifi_init as u64, 0, 0, 0);
7651 register_driver("via_envy24" as ptr<u8>, 4, drv_via_envy24_init as u64, 0, 0, 0);
7652 register_driver("cmi8738" as ptr<u8>, 4, drv_cmedia_cmi8738_init as u64, 0, 0, 0);
7653 register_driver("cmedia_oxygen" as ptr<u8>, 4, drv_cmedia_oxygen_init as u64, 0, 0, 0);
7654 register_driver("ess_solo1" as ptr<u8>, 4, drv_ess_solo1_init as u64, 0, 0, 0);
7655 register_driver("ymf724" as ptr<u8>, 4, drv_yamaha_ymf724_init as u64, 0, 0, 0);
7656 register_driver("fresco_xhci" as ptr<u8>, 6, drv_fresco_logic_xhci_init as u64, 0, 0, 0);
7657 register_driver("renesas_xhci" as ptr<u8>, 6, drv_renesas_xhci_init as u64, 0, 0, 0);
7658 register_driver("asmedia_xhci" as ptr<u8>, 6, drv_asmedia_xhci_init as u64, 0, 0, 0);
7659 register_driver("via_xhci" as ptr<u8>, 6, drv_via_xhci_init as u64, 0, 0, 0);
7660 register_driver("ti_xhci" as ptr<u8>, 6, drv_ti_xhci_init as u64, 0, 0, 0);
7661 register_driver("ti_firewire" as ptr<u8>, 2, drv_ti_firewire_init as u64, 0, 0, 0);
7662 register_driver("via_firewire" as ptr<u8>, 2, drv_via_firewire_init as u64, 0, 0, 0);
7663 register_driver("ricoh_firewire" as ptr<u8>, 2, drv_ricoh_firewire_init as u64, 0, 0, 0);
7664 register_driver("ricoh_sd" as ptr<u8>, 2, drv_ricoh_sd_init as u64, 0, 0, 0);
7665 register_driver("o2micro_sd" as ptr<u8>, 2, drv_o2micro_sd_init as u64, 0, 0, 0);
7666 register_driver("ene_sd" as ptr<u8>, 2, drv_ene_sd_init as u64, 0, 0, 0);
7667 }
7668 fn get_pci_vendor_name_ext(vendor_id: u16) -> ptr<u8> {
7669 if vendor_id == 0x8086 { return "Intel Corporation" as ptr<u8>; }
7670 if vendor_id == 0x1002 { return "Advanced Micro Devices, Inc. [AMD/ATI]" as ptr<u8>; }
7671 if vendor_id == 0x10DE { return "NVIDIA Corporation" as ptr<u8>; }
7672 if vendor_id == 0x10EC { return "Realtek Semiconductor Co., Ltd." as ptr<u8>; }
7673 if vendor_id == 0x14E4 { return "Broadcom Inc. and subsidiaries" as ptr<u8>; }
7674 if vendor_id == 0x1AF4 { return "Red Hat, Inc. [Virtio]" as ptr<u8>; }
7675 if vendor_id == 0x15AD { return "VMware" as ptr<u8>; }
7676 if vendor_id == 0x80EE { return "InnoTek Systemberatung GmbH [VirtualBox]" as ptr<u8>; }
7677 if vendor_id == 0x1022 { return "Advanced Micro Devices, Inc. [AMD]" as ptr<u8>; }
7678 if vendor_id == 0x104C { return "Texas Instruments" as ptr<u8>; }
7679 if vendor_id == 0x11AB { return "Marvell Technology Group Ltd." as ptr<u8>; }
7680 if vendor_id == 0x197B { return "JMicron Technology Corp." as ptr<u8>; }
7681 if vendor_id == 0x1014 { return "IBM Corporation" as ptr<u8>; }
7682 if vendor_id == 0x103C { return "Hewlett-Packard Company" as ptr<u8>; }
7683 if vendor_id == 0x1028 { return "Dell" as ptr<u8>; }
7684 if vendor_id == 0x1043 { return "ASUSTeK Computer Inc." as ptr<u8>; }
7685 if vendor_id == 0x1458 { return "Gigabyte Technology Co., Ltd" as ptr<u8>; }
7686 if vendor_id == 0x1462 { return "Micro-Star International Co., Ltd. [MSI]" as ptr<u8>; }
7687 if vendor_id == 0x15B3 { return "Mellanox Technologies" as ptr<u8>; }
7688 if vendor_id == 0x1B36 { return "Red Hat, Inc. [QEMU]" as ptr<u8>; }
7689 if vendor_id == 0x144D { return "Samsung Electronics Co Ltd" as ptr<u8>; }
7690 if vendor_id == 0x152D { return "JMicron Technology Corp. [NVMe]" as ptr<u8>; }
7691 if vendor_id == 0x1D0F { return "Amazon.com, Inc." as ptr<u8>; }
7692 if vendor_id == 0x1AE0 { return "Google, Inc." as ptr<u8>; }
7693 if vendor_id == 0x106B { return "Apple Inc." as ptr<u8>; }
7694 if vendor_id == 0x105A { return "Promise Technology, Inc." as ptr<u8>; }
7695 if vendor_id == 0x10B5 { return "PLX Technology, Inc." as ptr<u8>; }
7696 if vendor_id == 0x10DF { return "Emulex Corporation" as ptr<u8>; }
7697 if vendor_id == 0x1106 { return "VIA Technologies, Inc." as ptr<u8>; }
7698 if vendor_id == 0x1179 { return "Toshiba Corporation" as ptr<u8>; }
7699 if vendor_id == 0x1186 { return "D-Link System Inc" as ptr<u8>; }
7700 if vendor_id == 0x13F0 { return "Sundance Technology Inc / IC Plus Corp" as ptr<u8>; }
7701 if vendor_id == 0x168C { return "Qualcomm Atheros" as ptr<u8>; }
7702 if vendor_id == 0x1814 { return "Ralink corp." as ptr<u8>; }
7703 if vendor_id == 0x1B21 { return "ASMedia Technology Inc." as ptr<u8>; }
7704 if vendor_id == 0x8087 { return "Intel Corporation [Wireless]" as ptr<u8>; }
7705 if vendor_id == 0x1000 { return "LSI Logic / Symbios Logic" as ptr<u8>; }
7706 if vendor_id == 0x9005 { return "Adaptec" as ptr<u8>; }
7707 if vendor_id == 0x102B { return "Matrox Electronics Systems Ltd." as ptr<u8>; }
7708 if vendor_id == 0x121A { return "3Dfx Interactive, Inc." as ptr<u8>; }
7709 if vendor_id == 0x1013 { return "Cirrus Logic" as ptr<u8>; }
7710 if vendor_id == 0x104B { return "BusLogic" as ptr<u8>; }
7711 if vendor_id == 0x10EA { return "Intergraphics" as ptr<u8>; }
7712 if vendor_id == 0x108E { return "Sun Microsystems Computer Corp." as ptr<u8>; }
7713 if vendor_id == 0x1011 { return "Digital Equipment Corporation" as ptr<u8>; }
7714 if vendor_id == 0x10B7 { return "3Com Corporation" as ptr<u8>; }
7715 if vendor_id == 0x10D9 { return "Macronix, Inc. [MXIC]" as ptr<u8>; }
7716 if vendor_id == 0x1113 { return "Accton Technology Corporation" as ptr<u8>; }
7717 if vendor_id == 0x11AD { return "Lite-On Communications Inc" as ptr<u8>; }
7718 if vendor_id == 0x1259 { return "Allied Telesyn International" as ptr<u8>; }
7719 if vendor_id == 0x1371 { return "Creative Labs" as ptr<u8>; }
7720 if vendor_id == 0x1102 { return "Creative Labs [Audio]" as ptr<u8>; }
7721 if vendor_id == 0x13F6 { return "C-Media Electronics Inc" as ptr<u8>; }
7722 if vendor_id == 0x109E { return "Brooktree Corporation" as ptr<u8>; }
7723 if vendor_id == 0x10CC { return "Ericsson Microelectronics" as ptr<u8>; }
7724 if vendor_id == 0x12D8 { return "Pericom Semiconductor" as ptr<u8>; }
7725 if vendor_id == 0x1B73 { return "Fresco Logic" as ptr<u8>; }
7726 if vendor_id == 0x1912 { return "Renesas Technology Corp." as ptr<u8>; }
7727 if vendor_id == 0x1180 { return "Ricoh Co Ltd" as ptr<u8>; }
7728 if vendor_id == 0x1217 { return "O2 Micro, Inc." as ptr<u8>; }
7729 if vendor_id == 0x1524 { return "ENE Technology Inc" as ptr<u8>; }
7730 if vendor_id == 0x125D { return "ESS Technology" as ptr<u8>; }
7731 if vendor_id == 0x1073 { return "Yamaha Corporation" as ptr<u8>; }
7732 if vendor_id == 0x1039 { return "Silicon Integrated Systems [SiS]" as ptr<u8>; }
7733 if vendor_id == 0x10B9 { return "ULi Electronics Inc." as ptr<u8>; }
7734 if vendor_id == 0x5333 { return "S3 Graphics Ltd." as ptr<u8>; }
7735 return "Unknown Device Vendor" as ptr<u8>;
7736 }
7737 fn get_pci_device_name_ext(vendor_id: u16, device_id: u16) -> ptr<u8> {
7738 if vendor_id == 0x8086 {
7739 if device_id == 0x100E { return "82540EM Gigabit Ethernet Controller" as ptr<u8>; }
7740 if device_id == 0x100F { return "82545EM Gigabit Ethernet Controller" as ptr<u8>; }
7741 if device_id == 0x10D3 { return "82574L Gigabit Network Connection" as ptr<u8>; }
7742 if device_id == 0x10EA { return "82577LM Gigabit Network Connection" as ptr<u8>; }
7743 if device_id == 0x1502 { return "82579LM Gigabit Network Connection" as ptr<u8>; }
7744 if device_id == 0x1503 { return "82579V Gigabit Network Connection" as ptr<u8>; }
7745 if device_id == 0x153A { return "I217-LM Gigabit Network Connection" as ptr<u8>; }
7746 if device_id == 0x153B { return "I217-V Gigabit Network Connection" as ptr<u8>; }
7747 if device_id == 0x15B7 { return "I219-LM Gigabit Network Connection" as ptr<u8>; }
7748 if device_id == 0x15B8 { return "I219-V Gigabit Network Connection" as ptr<u8>; }
7749 if device_id == 0x10FB { return "82599ES 10-Gigabit SFI/SFP+ Network Connection" as ptr<u8>; }
7750 if device_id == 0x1528 { return "Ethernet Controller 10-Gigabit X540-AT2" as ptr<u8>; }
7751 if device_id == 0x2922 { return "82801IR/IO/P (ICH9) 6 port SATA Controller" as ptr<u8>; }
7752 if device_id == 0x1C02 { return "6 Series/C200 Series Chipset Family 6 port SATA" as ptr<u8>; }
7753 if device_id == 0x1E02 { return "7 Series/C210 Series Chipset Family 6-port SATA" as ptr<u8>; }
7754 if device_id == 0x8C02 { return "8 Series/C220 Series Chipset Family 6-port SATA" as ptr<u8>; }
7755 if device_id == 0xA102 { return "100 Series/C230 Series Chipset Family SATA" as ptr<u8>; }
7756 if device_id == 0xA282 { return "200 Series/Z370 Chipset Family SATA AHCI" as ptr<u8>; }
7757 if device_id == 0x0116 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
7758 if device_id == 0x0166 { return "3rd Gen Core processor Graphics Controller" as ptr<u8>; }
7759 if device_id == 0x0412 { return "4th Gen Core Processor Integrated Graphics" as ptr<u8>; }
7760 if device_id == 0x1912 { return "HD Graphics 530" as ptr<u8>; }
7761 if device_id == 0x3E92 { return "UHD Graphics 630 (Desktop)" as ptr<u8>; }
7762 if device_id == 0x9BC5 { return "CometLake-S GT2 [UHD Graphics 630]" as ptr<u8>; }
7763 if device_id == 0x2668 { return "82801FB/FBM/FR/FW/FRW High Definition Audio" as ptr<u8>; }
7764 if device_id == 0x284B { return "82801H (ICH8 Family) High Definition Audio" as ptr<u8>; }
7765 if device_id == 0x293E { return "82801I (ICH9 Family) High Definition Audio" as ptr<u8>; }
7766 if device_id == 0x1E20 { return "7 Series/C210 Series Chipset High Definition Audio" as ptr<u8>; }
7767 if device_id == 0xA170 { return "100 Series/C230 Series Chipset HD Audio" as ptr<u8>; }
7768 if device_id == 0x8C31 { return "8 Series/C220 Series Chipset Family USB xHCI" as ptr<u8>; }
7769 if device_id == 0xA12F { return "100 Series/C230 Series Chipset USB 3.0 xHCI" as ptr<u8>; }
7770 if device_id == 0x1E2D { return "7 Series/C210 Series Chipset USB Enhanced" as ptr<u8>; }
7771 if device_id == 0x24C2 { return "82801DB/DBM (ICH4/ICH4-M) USB UHCI" as ptr<u8>; }
7772 if device_id == 0xF1A5 { return "NVMe SSD Controller (Optane/760p)" as ptr<u8>; }
7773 if device_id == 0x4220 { return "PRO/Wireless 2200BG Network Connection" as ptr<u8>; }
7774 if device_id == 0x4229 { return "PRO/Wireless 4965 AG or AGN Network Connection" as ptr<u8>; }
7775 if device_id == 0x0085 { return "Centrino Advanced-N 6205 [Taylor Peak]" as ptr<u8>; }
7776 if device_id == 0x08B1 { return "Wireless 7260" as ptr<u8>; }
7777 if device_id == 0x24FB { return "Dual Band Wireless-AC 3160" as ptr<u8>; }
7778 if device_id == 0x24FD { return "Dual Band Wireless-AC 8265" as ptr<u8>; }
7779 if device_id == 0x2723 { return "Wi-Fi 6 AX200" as ptr<u8>; }
7780 if device_id == 0x2725 { return "Wi-Fi 6 AX210/AX1675 2x2" as ptr<u8>; }
7781 if device_id == 0x7113 { return "PIIX4/4E/4M IDE Controller" as ptr<u8>; }
7782 if device_id == 0x1237 { return "440FX - 82441FX PMC" as ptr<u8>; }
7783 if device_id == 0x7000 { return "82371SB PIIX3 ISA" as ptr<u8>; }
7784 if device_id == 0x7110 { return "82371AB/EB/MB PIIX4 ISA" as ptr<u8>; }
7785 if device_id == 0x7111 { return "82371AB/EB/MB PIIX4 IDE" as ptr<u8>; }
7786 if device_id == 0x7112 { return "82371AB/EB/MB PIIX4 USB" as ptr<u8>; }
7787 return "Intel Controller" as ptr<u8>;
7788 }
7789 if vendor_id == 0x10EC {
7790 if device_id == 0x8139 { return "RTL-8100/8101L/8139 PCI Fast Ethernet" as ptr<u8>; }
7791 if device_id == 0x8168 { return "RTL8111/8168/8411 PCI Express Gigabit" as ptr<u8>; }
7792 if device_id == 0x8169 { return "RTL8169 PCI Gigabit Ethernet" as ptr<u8>; }
7793 if device_id == 0x8125 { return "RTL8125 2.5GbE Controller" as ptr<u8>; }
7794 if device_id == 0x818B { return "RTL8192EE PCIe Wireless Network Adapter" as ptr<u8>; }
7795 if device_id == 0x8821 { return "RTL8821AE 802.11ac PCIe Wireless" as ptr<u8>; }
7796 if device_id == 0x8822 { return "RTL8822BE 802.11a/b/g/n/ac WiFi" as ptr<u8>; }
7797 if device_id == 0x522A { return "RTS522A PCI Express Card Reader" as ptr<u8>; }
7798 if device_id == 0x0282 { return "RTL8188EE Wireless Network Adapter" as ptr<u8>; }
7799 if device_id == 0x8161 { return "RTL8162 Fast Ethernet" as ptr<u8>; }
7800 if device_id == 0x8167 { return "RTL8167 Gigabit Ethernet" as ptr<u8>; }
7801 if device_id == 0x5209 { return "RTS5209 PCI Express Card Reader" as ptr<u8>; }
7802 if device_id == 0x5227 { return "RTS5227 PCI Express Card Reader" as ptr<u8>; }
7803 if device_id == 0x5289 { return "RTL8411B PCI Express Card Reader" as ptr<u8>; }
7804 return "Realtek Device" as ptr<u8>;
7805 }
7806 if vendor_id == 0x10DE {
7807 if device_id == 0x0402 { return "GeForce 8600 GT" as ptr<u8>; }
7808 if device_id == 0x0611 { return "GeForce 8800 GT" as ptr<u8>; }
7809 if device_id == 0x0A20 { return "GeForce GT 220" as ptr<u8>; }
7810 if device_id == 0x06C0 { return "GeForce GTX 480" as ptr<u8>; }
7811 if device_id == 0x1080 { return "GeForce GTX 580" as ptr<u8>; }
7812 if device_id == 0x1180 { return "GeForce GTX 680" as ptr<u8>; }
7813 if device_id == 0x13C2 { return "GeForce GTX 970" as ptr<u8>; }
7814 if device_id == 0x13C0 { return "GeForce GTX 980" as ptr<u8>; }
7815 if device_id == 0x1C03 { return "GeForce GTX 1060 6GB" as ptr<u8>; }
7816 if device_id == 0x1B81 { return "GeForce GTX 1070" as ptr<u8>; }
7817 if device_id == 0x1B06 { return "GeForce GTX 1080 Ti" as ptr<u8>; }
7818 if device_id == 0x1E84 { return "GeForce RTX 2070" as ptr<u8>; }
7819 if device_id == 0x1E07 { return "GeForce RTX 2080 Ti" as ptr<u8>; }
7820 if device_id == 0x2204 { return "GeForce RTX 3090" as ptr<u8>; }
7821 if device_id == 0x2484 { return "GeForce RTX 3070" as ptr<u8>; }
7822 if device_id == 0x2684 { return "GeForce RTX 4090" as ptr<u8>; }
7823 if device_id == 0x28E0 { return "GeForce RTX 4050 Laptop GPU" as ptr<u8>; }
7824 if device_id == 0x0E0A { return "GF119 HDMI Audio Controller" as ptr<u8>; }
7825 if device_id == 0x0FB0 { return "GM200 High Definition Audio" as ptr<u8>; }
7826 if device_id == 0x10F0 { return "GP104 High Definition Audio" as ptr<u8>; }
7827 if device_id == 0x10FA { return "TU104 HD Audio Controller" as ptr<u8>; }
7828 if device_id == 0x0059 { return "CK804 Serial ATA Controller" as ptr<u8>; }
7829 if device_id == 0x0054 { return "CK804 Memory Controller" as ptr<u8>; }
7830 if device_id == 0x0055 { return "CK804 IDE" as ptr<u8>; }
7831 if device_id == 0x03EF { return "MCP61 Ethernet" as ptr<u8>; }
7832 if device_id == 0x0DF4 { return "GeForce GT 540M" as ptr<u8>; }
7833 if device_id == 0x0FC6 { return "GeForce GTX 650" as ptr<u8>; }
7834 if device_id == 0x1140 { return "GF117M [GeForce 610M/710M]" as ptr<u8>; }
7835 if device_id == 0x139A { return "GM107M [GeForce GTX 950M]" as ptr<u8>; }
7836 if device_id == 0x1C20 { return "GP106M [GeForce GTX 1060 Mobile]" as ptr<u8>; }
7837 if device_id == 0x1F11 { return "TU106M [GeForce RTX 2060 Mobile]" as ptr<u8>; }
7838 if device_id == 0x2520 { return "GA106M [GeForce RTX 3060 Mobile]" as ptr<u8>; }
7839 return "NVIDIA Graphics / Multimedia" as ptr<u8>;
7840 }
7841 if vendor_id == 0x1002 {
7842 if device_id == 0x6738 { return "Radeon HD 6870" as ptr<u8>; }
7843 if device_id == 0x6798 { return "Radeon HD 7970 / R9 280X" as ptr<u8>; }
7844 if device_id == 0x67B1 { return "Radeon R9 290 / 390" as ptr<u8>; }
7845 if device_id == 0x67DF { return "Radeon RX 470/480/570/580/590" as ptr<u8>; }
7846 if device_id == 0x687F { return "Radeon RX Vega 56/64" as ptr<u8>; }
7847 if device_id == 0x731F { return "Radeon RX 5700 XT" as ptr<u8>; }
7848 if device_id == 0x73BF { return "Radeon RX 6800 XT / 6900 XT" as ptr<u8>; }
7849 if device_id == 0x744C { return "Radeon RX 7900 XTX" as ptr<u8>; }
7850 if device_id == 0x4383 { return "SB7x0/SB8x0/SB9x0 High Definition Audio" as ptr<u8>; }
7851 if device_id == 0x1457 { return "Family 17h HD Audio Controller" as ptr<u8>; }
7852 if device_id == 0x4391 { return "SB7x0/SB8x0/SB9x0 SATA [AHCI]" as ptr<u8>; }
7853 if device_id == 0x7901 { return "FCH SATA Controller [AHCI]" as ptr<u8>; }
7854 if device_id == 0x515E { return "Radeon X1300/X1550" as ptr<u8>; }
7855 if device_id == 0x9540 { return "Radeon HD 4350/4550" as ptr<u8>; }
7856 if device_id == 0x68B8 { return "Radeon HD 5770" as ptr<u8>; }
7857 if device_id == 0x6819 { return "Radeon HD 7870" as ptr<u8>; }
7858 if device_id == 0x15D8 { return "Raven Ridge [Radeon Vega Series]" as ptr<u8>; }
7859 if device_id == 0x1636 { return "Renoir [Radeon Vega Series]" as ptr<u8>; }
7860 if device_id == 0x73A5 { return "Navi 22 [Radeon RX 6700/6700 XT]" as ptr<u8>; }
7861 if device_id == 0x7480 { return "Navi 31 [Radeon RX 7900 XT]" as ptr<u8>; }
7862 return "AMD/ATI Display / Multimedia" as ptr<u8>;
7863 }
7864 if vendor_id == 0x1AF4 {
7865 if device_id == 0x1000 { return "VirtIO Network Device" as ptr<u8>; }
7866 if device_id == 0x1001 { return "VirtIO Block Device" as ptr<u8>; }
7867 if device_id == 0x1002 { return "VirtIO Memory Balloon" as ptr<u8>; }
7868 if device_id == 0x1003 { return "VirtIO Console" as ptr<u8>; }
7869 if device_id == 0x1004 { return "VirtIO SCSI" as ptr<u8>; }
7870 if device_id == 0x1005 { return "VirtIO RNG" as ptr<u8>; }
7871 if device_id == 0x1041 { return "VirtIO Network Device (Modern)" as ptr<u8>; }
7872 if device_id == 0x1042 { return "VirtIO Block Device (Modern)" as ptr<u8>; }
7873 if device_id == 0x1050 { return "VirtIO GPU" as ptr<u8>; }
7874 if device_id == 0x1052 { return "VirtIO Input Device" as ptr<u8>; }
7875 if device_id == 0x1053 { return "VirtIO Socket Device" as ptr<u8>; }
7876 return "VirtIO Standard Device" as ptr<u8>;
7877 }
7878 if vendor_id == 0x15AD {
7879 if device_id == 0x0405 { return "VMware SVGA II Adapter" as ptr<u8>; }
7880 if device_id == 0x07B0 { return "VMware VMXNET3 Ethernet" as ptr<u8>; }
7881 if device_id == 0x07A0 { return "VMware PVSCSI SCSI" as ptr<u8>; }
7882 if device_id == 0x0770 { return "VMware USB2 EHCI" as ptr<u8>; }
7883 if device_id == 0x0774 { return "VMware USB1 UHCI" as ptr<u8>; }
7884 return "VMware Virtual Device" as ptr<u8>;
7885 }
7886 if vendor_id == 0x80EE {
7887 if device_id == 0xBEEF { return "VirtualBox Graphics Adapter" as ptr<u8>; }
7888 if device_id == 0xCAFE { return "VirtualBox Guest Service" as ptr<u8>; }
7889 return "VirtualBox Virtual Device" as ptr<u8>;
7890 }
7891 if vendor_id == 0x144D {
7892 if device_id == 0xA802 { return "Samsung SM951 NVMe" as ptr<u8>; }
7893 if device_id == 0xA804 { return "Samsung 960 EVO/PRO NVMe" as ptr<u8>; }
7894 if device_id == 0xA808 { return "Samsung 970 EVO/PRO NVMe" as ptr<u8>; }
7895 if device_id == 0xA80A { return "Samsung 980 PRO NVMe" as ptr<u8>; }
7896 if device_id == 0xA80C { return "Samsung 990 PRO NVMe" as ptr<u8>; }
7897 if device_id == 0xA809 { return "Samsung PM9A1 NVMe" as ptr<u8>; }
7898 return "Samsung NVMe Controller" as ptr<u8>;
7899 }
7900 if vendor_id == 0x14E4 {
7901 if device_id == 0x1659 { return "NetXtreme BCM5721 Gigabit" as ptr<u8>; }
7902 if device_id == 0x1677 { return "NetXtreme BCM5751 Gigabit" as ptr<u8>; }
7903 if device_id == 0x4311 { return "BCM4311 802.11b/g WLAN" as ptr<u8>; }
7904 if device_id == 0x4322 { return "BCM4322 802.11a/b/g/n Wireless" as ptr<u8>; }
7905 if device_id == 0x4360 { return "BCM4360 802.11ac Wireless" as ptr<u8>; }
7906 if device_id == 0x1692 { return "NetLink BCM57780 Gigabit" as ptr<u8>; }
7907 if device_id == 0x4331 { return "BCM4331 802.11a/b/g/n" as ptr<u8>; }
7908 if device_id == 0x43A0 { return "BCM4360 802.11ac Wireless" as ptr<u8>; }
7909 return "Broadcom Communications" as ptr<u8>;
7910 }
7911 if vendor_id == 0x168C {
7912 if device_id == 0x002B { return "AR9285 Wireless Network Adapter" as ptr<u8>; }
7913 if device_id == 0x002E { return "AR9287 Wireless Network Adapter" as ptr<u8>; }
7914 if device_id == 0x0032 { return "AR9485 Wireless Network Adapter" as ptr<u8>; }
7915 if device_id == 0x003C { return "QCA986x/988x 802.11ac Wireless" as ptr<u8>; }
7916 if device_id == 0x0013 { return "AR5212/AR5213 Wireless Network Adapter" as ptr<u8>; }
7917 if device_id == 0x001C { return "AR2424 Wireless Network Adapter" as ptr<u8>; }
7918 if device_id == 0x0030 { return "AR9300 Wireless Network Adapter" as ptr<u8>; }
7919 if device_id == 0x003E { return "QCA6174 802.11ac Wireless" as ptr<u8>; }
7920 if device_id == 0x0042 { return "QCA9377 802.11ac Wireless" as ptr<u8>; }
7921 return "Atheros Wireless Device" as ptr<u8>;
7922 }
7923 if vendor_id == 0x1000 {
7924 if device_id == 0x0054 { return "MegaRAID SAS 2008" as ptr<u8>; }
7925 if device_id == 0x005B { return "MegaRAID SAS 2108" as ptr<u8>; }
7926 if device_id == 0x005D { return "MegaRAID SAS 2208" as ptr<u8>; }
7927 if device_id == 0x005F { return "MegaRAID SAS 3008" as ptr<u8>; }
7928 if device_id == 0x00cf { return "MegaRAID SAS 3108" as ptr<u8>; }
7929 return "LSI Logic Storage Controller" as ptr<u8>;
7930 }
7931 if vendor_id == 0x1102 {
7932 if device_id == 0x0002 { return "Sound Blaster Live! (EMU10K1)" as ptr<u8>; }
7933 if device_id == 0x0004 { return "Sound Blaster Audigy (EMU10K2)" as ptr<u8>; }
7934 if device_id == 0x0005 { return "Sound Blaster X-Fi" as ptr<u8>; }
7935 if device_id == 0x000A { return "Sound Blaster X-Fi Titanium" as ptr<u8>; }
7936 if device_id == 0x0012 { return "Sound Blaster Recon3D" as ptr<u8>; }
7937 return "Creative Audio Device" as ptr<u8>;
7938 }
7939 if vendor_id == 0x1011 {
7940 if device_id == 0x0009 { return "DECchip 21140 [FasterNet]" as ptr<u8>; }
7941 if device_id == 0x0019 { return "DECchip 21142/43" as ptr<u8>; }
7942 return "DEC Ethernet Controller" as ptr<u8>;
7943 }
7944 if vendor_id == 0x10B7 {
7945 if device_id == 0x9050 { return "3c905 100BaseTX" as ptr<u8>; }
7946 if device_id == 0x9055 { return "3c905B 100BaseTX" as ptr<u8>; }
7947 if device_id == 0x9200 { return "3c905C-TX/TX-M" as ptr<u8>; }
7948 return "3Com Fast Ethernet" as ptr<u8>;
7949 }
7950 if vendor_id == 0x11AB {
7951 if device_id == 0x4364 { return "88E8056 PCI-E Gigabit Ethernet" as ptr<u8>; }
7952 if device_id == 0x4380 { return "88E8057 PCI-E Gigabit Ethernet" as ptr<u8>; }
7953 if device_id == 0x9123 { return "88SE9123 PCIe SATA 6.0 Gb/s" as ptr<u8>; }
7954 if device_id == 0x9215 { return "88SE9215 PCIe SATA 6.0 Gb/s" as ptr<u8>; }
7955 return "Marvell Technology Device" as ptr<u8>;
7956 }
7957 if vendor_id == 0x1B21 {
7958 if device_id == 0x0612 { return "ASM1062 Serial ATA Controller" as ptr<u8>; }
7959 if device_id == 0x1042 { return "ASM1042 SuperSpeed USB Host" as ptr<u8>; }
7960 if device_id == 0x1142 { return "ASM1142 USB 3.1 Host" as ptr<u8>; }
7961 if device_id == 0x2142 { return "ASM2142 USB 3.1 Host" as ptr<u8>; }
7962 if device_id == 0x3242 { return "ASM3242 USB 3.2 Host" as ptr<u8>; }
7963 return "ASMedia Host Controller" as ptr<u8>;
7964 }
7965 if vendor_id == 0x1039 {
7966 if device_id == 0x0190 { return "SiS900 PCI Fast Ethernet" as ptr<u8>; }
7967 if device_id == 0x0191 { return "SiS191 Gigabit Ethernet" as ptr<u8>; }
7968 if device_id == 0x0180 { return "SiS180 SATA Controller" as ptr<u8>; }
7969 if device_id == 0x7012 { return "SiS7012 AC'97 Sound" as ptr<u8>; }
7970 if device_id == 0x7001 { return "SiS5597/5598/5600 USB UHCI" as ptr<u8>; }
7971 return "SiS Chipset Component" as ptr<u8>;
7972 }
7973 if vendor_id == 0x1106 {
7974 if device_id == 0x3065 { return "VT6102/VT6103 [Rhine-II]" as ptr<u8>; }
7975 if device_id == 0x3106 { return "VT6105/VT6106S [Rhine-III]" as ptr<u8>; }
7976 if device_id == 0x3119 { return "VT6120/VT6121/VT6122 Velocity Gigabit" as ptr<u8>; }
7977 if device_id == 0x3149 { return "VT6420 SATA RAID" as ptr<u8>; }
7978 if device_id == 0x3249 { return "VT6421 IDE RAID" as ptr<u8>; }
7979 if device_id == 0x0591 { return "VT82C598/694x [Apollo Pro]" as ptr<u8>; }
7980 if device_id == 0x3038 { return "VT82xxxxx UHCI USB 1.1" as ptr<u8>; }
7981 if device_id == 0x3104 { return "USB 2.0" as ptr<u8>; }
7982 if device_id == 0x3288 { return "VT8237A HD Audio Controller" as ptr<u8>; }
7983 if device_id == 0x3059 { return "VT8233/A/8235/8237 AC97 Audio" as ptr<u8>; }
7984 return "VIA Technologies Device" as ptr<u8>;
7985 }
7986 if vendor_id == 0x15B3 {
7987 if device_id == 0x1003 { return "MT27500 Family [ConnectX-3]" as ptr<u8>; }
7988 if device_id == 0x1013 { return "MT27700 Family [ConnectX-4]" as ptr<u8>; }
7989 if device_id == 0x1015 { return "MT27710 Family [ConnectX-4 Lx]" as ptr<u8>; }
7990 if device_id == 0x1017 { return "MT27800 Family [ConnectX-5]" as ptr<u8>; }
7991 if device_id == 0x101B { return "MT28908 Family [ConnectX-6]" as ptr<u8>; }
7992 return "Mellanox Network Adapter" as ptr<u8>;
7993 }
7994 if vendor_id == 0x121A {
7995 if device_id == 0x0001 { return "Voodoo Graphics" as ptr<u8>; }
7996 if device_id == 0x0002 { return "Voodoo 2" as ptr<u8>; }
7997 if device_id == 0x0003 { return "Voodoo Banshee" as ptr<u8>; }
7998 if device_id == 0x0004 { return "Voodoo 3" as ptr<u8>; }
7999 if device_id == 0x0005 { return "Voodoo 4/5" as ptr<u8>; }
8000 return "3Dfx Voodoo Accelerator" as ptr<u8>;
8001 }
8002 if vendor_id == 0x102B {
8003 if device_id == 0x0519 { return "MGA Millennium" as ptr<u8>; }
8004 if device_id == 0x051B { return "MGA Mystique" as ptr<u8>; }
8005 if device_id == 0x0521 { return "MGA G200" as ptr<u8>; }
8006 if device_id == 0x0525 { return "MGA G400/G450" as ptr<u8>; }
8007 if device_id == 0x2527 { return "MGA G550" as ptr<u8>; }
8008 return "Matrox Graphics" as ptr<u8>;
8009 }
8010 if vendor_id == 0x5333 {
8011 if device_id == 0x8811 { return "Trio32/64/64V+" as ptr<u8>; }
8012 if device_id == 0x8A01 { return "ViRGE/DX or /GX" as ptr<u8>; }
8013 if device_id == 0x8A22 { return "Savage 3D" as ptr<u8>; }
8014 if device_id == 0x8C10 { return "Savage/MX" as ptr<u8>; }
8015 if device_id == 0x8D04 { return "Savage4" as ptr<u8>; }
8016 if device_id == 0x8C2E { return "SuperSavage IX/C" as ptr<u8>; }
8017 return "S3 Graphics Device" as ptr<u8>;
8018 }
8019
8020 return "Generic Peripheral Component" as ptr<u8>;
8021 }
8022 struct CpuState {
8023 ds: u16,
8024 es: u16,
8025 fs: u16,
8026 gs: u16,
8027 rax: u64,
8028 rbx: u64,
8029 rcx: u64,
8030 rdx: u64,
8031 rsi: u64,
8032 rdi: u64,
8033 rbp: u64,
8034 r8: u64,
8035 r9: u64,
8036 r10: u64,
8037 r11: u64,
8038 r12: u64,
8039 r13: u64,
8040 r14: u64,
8041 r15: u64,
8042 int_num: u64,
8043 error_code: u64,
8044 rip: u64,
8045 cs: u64,
8046 rflags: u64,
8047 rsp: u64,
8048 ss: u64,
8049 }
8050 fn get_exception_name(vector: u64) -> ptr<u8> {
8051 if vector == 0 { return "Divide By Zero Exception" as ptr<u8>; }
8052 if vector == 1 { return "Debug Exception" as ptr<u8>; }
8053 if vector == 2 { return "Non-maskable Interrupt" as ptr<u8>; }
8054 if vector == 3 { return "Breakpoint Exception" as ptr<u8>; }
8055 if vector == 4 { return "Overflow Exception" as ptr<u8>; }
8056 if vector == 5 { return "Bound Range Exceeded" as ptr<u8>; }
8057 if vector == 6 { return "Invalid Opcode" as ptr<u8>; }
8058 if vector == 7 { return "Device Not Available" as ptr<u8>; }
8059 if vector == 8 { return "Double Fault" as ptr<u8>; }
8060 if vector == 9 { return "Coprocessor Segment Overrun" as ptr<u8>; }
8061 if vector == 10 { return "Invalid TSS" as ptr<u8>; }
8062 if vector == 11 { return "Segment Not Present" as ptr<u8>; }
8063 if vector == 12 { return "Stack-Segment Fault" as ptr<u8>; }
8064 if vector == 13 { return "General Protection Fault" as ptr<u8>; }
8065 if vector == 14 { return "Page Fault" as ptr<u8>; }
8066 if vector == 15 { return "Reserved" as ptr<u8>; }
8067 if vector == 16 { return "x87 Floating-Point Exception" as ptr<u8>; }
8068 if vector == 17 { return "Alignment Check" as ptr<u8>; }
8069 if vector == 18 { return "Machine Check" as ptr<u8>; }
8070 if vector == 19 { return "SIMD Floating-Point Exception" as ptr<u8>; }
8071 if vector == 20 { return "Virtualization Exception" as ptr<u8>; }
8072 if vector == 21 { return "Control Protection Exception" as ptr<u8>; }
8073 if vector == 28 { return "Hypervisor Injection Exception" as ptr<u8>; }
8074 if vector == 29 { return "VMM Communication Exception" as ptr<u8>; }
8075 if vector == 30 { return "Security Exception" as ptr<u8>; }
8076 return "Unknown Interrupt/Exception" as ptr<u8>;
8077 }
8078 fn render_panic_screen(state: ptr<CpuState>, cr2: u64, cr3: u64) {
8079 panic_clear_screen(VGA_COLOR_WHITE_ON_RED);
8080
8081 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
8082 panic_write_padded_string(" W KERNEL PANIC - CRITICAL SYSTEM HALT " as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8083 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
8084
8085 panic_print_string("\nEXCEPTION: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8086 let ext_name = get_exception_name((*state).int_num);
8087 panic_print_string(ext_name, VGA_COLOR_WHITE_ON_RED);
8088 panic_print_string(" (" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8089 panic_print_hex((*state).int_num, VGA_COLOR_WHITE_ON_RED);
8090 panic_print_string(")\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8091
8092 panic_print_string("ERROR CODE: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8093 panic_print_hex((*state).error_code, VGA_COLOR_WHITE_ON_RED);
8094 panic_print_string("\n\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8095
8096 panic_write_padded_string("--- CPU REGISTERS ---" as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8097 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8098
8099 panic_print_string("RAX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8100 panic_print_hex((*state).rax, VGA_COLOR_WHITE_ON_RED);
8101 panic_print_string(" RBX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8102 panic_print_hex((*state).rbx, VGA_COLOR_WHITE_ON_RED);
8103 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8104
8105 panic_print_string("RCX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8106 panic_print_hex((*state).rcx, VGA_COLOR_WHITE_ON_RED);
8107 panic_print_string(" RDX: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8108 panic_print_hex((*state).rdx, VGA_COLOR_WHITE_ON_RED);
8109 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8110
8111 panic_print_string("RSI: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8112 panic_print_hex((*state).rsi, VGA_COLOR_WHITE_ON_RED);
8113 panic_print_string(" RDI: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8114 panic_print_hex((*state).rdi, VGA_COLOR_WHITE_ON_RED);
8115 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8116
8117 panic_print_string("RBP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8118 panic_print_hex((*state).rbp, VGA_COLOR_WHITE_ON_RED);
8119 panic_print_string(" RSP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8120 panic_print_hex((*state).rsp, VGA_COLOR_WHITE_ON_RED);
8121 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8122
8123 panic_print_string("R8 : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8124 panic_print_hex((*state).r8, VGA_COLOR_WHITE_ON_RED);
8125 panic_print_string(" R9 : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8126 panic_print_hex((*state).r9, VGA_COLOR_WHITE_ON_RED);
8127 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8128
8129 panic_print_string("R10: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8130 panic_print_hex((*state).r10, VGA_COLOR_WHITE_ON_RED);
8131 panic_print_string(" R11: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8132 panic_print_hex((*state).r11, VGA_COLOR_WHITE_ON_RED);
8133 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8134
8135 panic_print_string("R12: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8136 panic_print_hex((*state).r12, VGA_COLOR_WHITE_ON_RED);
8137 panic_print_string(" R13: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8138 panic_print_hex((*state).r13, VGA_COLOR_WHITE_ON_RED);
8139 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8140
8141 panic_print_string("R14: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8142 panic_print_hex((*state).r14, VGA_COLOR_WHITE_ON_RED);
8143 panic_print_string(" R15: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8144 panic_print_hex((*state).r15, VGA_COLOR_WHITE_ON_RED);
8145 panic_print_string("\n\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8146
8147 panic_write_padded_string("--- CONTROL REGISTERS & SEGMENTS ---" as ptr<u8>, 80, VGA_COLOR_WHITE_ON_RED);
8148 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8149
8150 panic_print_string("RIP: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8151 panic_print_hex((*state).rip, VGA_COLOR_WHITE_ON_RED);
8152 panic_print_string(" RFL: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8153 panic_print_hex((*state).rflags, VGA_COLOR_WHITE_ON_RED);
8154 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8155
8156 panic_print_string("CR2: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8157 panic_print_hex(cr2, VGA_COLOR_WHITE_ON_RED);
8158 panic_print_string(" CR3: " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8159 panic_print_hex(cr3, VGA_COLOR_WHITE_ON_RED);
8160 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8161
8162 panic_print_string("CS : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8163 panic_print_hex((*state).cs as u64, VGA_COLOR_WHITE_ON_RED);
8164 panic_print_string(" SS : " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8165 panic_print_hex((*state).ss as u64, VGA_COLOR_WHITE_ON_RED);
8166 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8167 }
8168 fn dump_stack_trace(rbp: u64, max_frames: u64) {
8169 panic_print_string("\n--- STACK TRACE ---\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8170 let mut current_rbp = rbp;
8171 let mut frame_count: u64 = 0;
8172
8173 while current_rbp != 0 {
8174 if frame_count >= max_frames {
8175 break;
8176 }
8177
8178 let rip_ptr = (current_rbp + 8) as ptr<u64>;
8179 let rip = *rip_ptr;
8180
8181 if rip == 0 {
8182 break;
8183 }
8184
8185 panic_print_string(" [" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8186 panic_print_hex(frame_count, VGA_COLOR_WHITE_ON_RED);
8187 panic_print_string("] " as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8188 panic_print_hex(rip, VGA_COLOR_WHITE_ON_RED);
8189 panic_print_string("\n" as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8190
8191 let next_rbp_ptr = current_rbp as ptr<u64>;
8192 current_rbp = *next_rbp_ptr;
8193 frame_count = frame_count + 1;
8194 }
8195 }
8196 fn kernel_panic_handler(state: ptr<CpuState>) {
8197 let cr2_val: u64 = 0;
8198 let cr3_val: u64 = 0;
8199
8200 render_panic_screen(state, cr2_val, cr3_val);
8201 dump_stack_trace((*state).rbp, 8);
8202
8203 panic_print_separator(VGA_COLOR_WHITE_ON_RED);
8204 panic_print_string("SYSTEM HALTED." as ptr<u8>, VGA_COLOR_WHITE_ON_RED);
8205
8206 while true {}
8207 }
8208 struct IdtEntry {
8209 base_low: u16,
8210 sel: u16,
8211 ist: u8,
8212 flags: u8,
8213 base_mid: u16,
8214 base_high: u32,
8215 reserved: u32,
8216 }
8217 struct IdtPtr {
8218 limit: u16,
8219 base: u64,
8220 }
8221 let mut idt: [IdtEntry; 256];
8222 let mut idtp: IdtPtr;
8223 fn idt_set_gate(num: u8, base: u64, sel: u16, flags: u8) {
8224 let index = num as usize;
8225 idt[index].base_low = (base & 0xFFFF) as u16;
8226 idt[index].base_mid = ((base >> 16) & 0xFFFF) as u16;
8227 idt[index].base_high = (base >> 32) as u32;
8228 idt[index].sel = sel;
8229 idt[index].ist = 0;
8230 idt[index].flags = flags;
8231 idt[index].reserved = 0;
8232 }
8233 fn idt_install() {
8234 idtp.limit = (256 * 16) - 1;
8235 idtp.base = &idt[0] as ptr<IdtEntry> as u64;
8236 let mut i: u64 = 0;
8237 while i < 256 {
8238 idt_set_gate(i as u8, 0, 0x08, 0x8E);
8239 i = i + 1;
8240 }
8241 }
8242 fn fault_divide_error(state: ptr<CpuState>) { kernel_panic_handler(state); }
8243 fn fault_debug(state: ptr<CpuState>) { kernel_panic_handler(state); }
8244 fn fault_nmi(state: ptr<CpuState>) { kernel_panic_handler(state); }
8245 fn fault_breakpoint(state: ptr<CpuState>) { kernel_panic_handler(state); }
8246 fn fault_overflow(state: ptr<CpuState>) { kernel_panic_handler(state); }
8247 fn fault_bounds(state: ptr<CpuState>) { kernel_panic_handler(state); }
8248 fn fault_invalid_opcode(state: ptr<CpuState>) { kernel_panic_handler(state); }
8249 fn fault_device_not_available(state: ptr<CpuState>) { kernel_panic_handler(state); }
8250 fn fault_double_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
8251 fn fault_coproc_segment_overrun(state: ptr<CpuState>) { kernel_panic_handler(state); }
8252 fn fault_invalid_tss(state: ptr<CpuState>) { kernel_panic_handler(state); }
8253 fn fault_segment_not_present(state: ptr<CpuState>) { kernel_panic_handler(state); }
8254 fn fault_stack_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
8255 fn fault_general_protection(state: ptr<CpuState>) { kernel_panic_handler(state); }
8256 fn fault_page_fault(state: ptr<CpuState>) { kernel_panic_handler(state); }
8257 fn fault_x87_fpu(state: ptr<CpuState>) { kernel_panic_handler(state); }
8258 fn fault_alignment_check(state: ptr<CpuState>) { kernel_panic_handler(state); }
8259 fn fault_machine_check(state: ptr<CpuState>) { kernel_panic_handler(state); }
8260 fn fault_simd_fpu(state: ptr<CpuState>) { kernel_panic_handler(state); }
8261 fn fault_virtualization(state: ptr<CpuState>) { kernel_panic_handler(state); }
8262 struct Process {
8263 pid: u64,
8264 rsp: u64,
8265 rip: u64,
8266 cr3: u64,
8267 state: u8,
8268 time_slice: u64,
8269 }
8270 let mut process_table: [Process; 256];
8271 let mut current_pid: u64 = 0;
8272 let mut total_processes: u64 = 0;
8273 fn scheduler_init() {
8274 let mut i: u64 = 0;
8275 while i < 256 {
8276 process_table[i as usize].pid = 0;
8277 process_table[i as usize].state = 0;
8278 i = i + 1;
8279 }
8280 }
8281 fn process_create(entry_point: u64, stack_pointer: u64, page_dir: u64) -> u64 {
8282 if total_processes >= 256 {
8283 return 0;
8284 }
8285
8286 let pid = total_processes + 1;
8287 let index = total_processes as usize;
8288
8289 process_table[index].pid = pid;
8290 process_table[index].rip = entry_point;
8291 process_table[index].rsp = stack_pointer;
8292 process_table[index].cr3 = page_dir;
8293 process_table[index].state = 1;
8294 process_table[index].time_slice = 15;
8295
8296 total_processes = total_processes + 1;
8297 return pid;
8298 }
8299 fn schedule_next(current_rsp: u64) -> u64 {
8300 if total_processes == 0 {
8301 return current_rsp;
8302 }
8303 if current_pid > 0 {
8304 let curr_idx = (current_pid - 1) as usize;
8305 process_table[curr_idx].rsp = current_rsp;
8306
8307 if process_table[curr_idx].time_slice > 0 {
8308 process_table[curr_idx].time_slice = process_table[curr_idx].time_slice - 1;
8309 if process_table[curr_idx].time_slice > 0 {
8310 return current_rsp;
8311 }
8312 }
8313 process_table[curr_idx].time_slice = 15;
8314 }
8315 current_pid = current_pid + 1;
8316 if current_pid > total_processes {
8317 current_pid = 1;
8318 }
8319 let next_idx = (current_pid - 1) as usize;
8320 return process_table[next_idx].rsp;
8321 }
8322 fn timer_phase(hz: u32) {
8323 let divisor = 1193180 / hz;
8324 outb(0x43, 0x36);
8325 outb(0x40, (divisor & 0xFF) as u8);
8326 outb(0x40, ((divisor >> 8) & 0xFF) as u8);
8327 }
8328 let mut timer_ticks: u64 = 0;
8329 fn timer_handler(state: ptr<CpuState>) -> u64 {
8330 timer_ticks = timer_ticks + 1;
8331 let next_rsp = schedule_next((*state).rsp);
8332 outb(0x20, 0x20);
8333 return next_rsp;
8334 }
8335 let mut memory_bitmap: [u64; 32768];
8336 let mut total_memory_pages: u64 = 0;
8337 let mut used_memory_pages: u64 = 0;
8338 fn set_bit(bitmap: ptr<u64>, index: u64) {
8339 let array_index = index / 64;
8340 let bit_index = index % 64;
8341 let current = *(bitmap + array_index);
8342 *(bitmap + array_index) = current | (1 << bit_index);
8343 }
8344 fn clear_bit(bitmap: ptr<u64>, index: u64) {
8345 let array_index = index / 64;
8346 let bit_index = index % 64;
8347 let current = *(bitmap + array_index);
8348 *(bitmap + array_index) = current & !(1 << bit_index);
8349 }
8350 fn test_bit(bitmap: ptr<u64>, index: u64) -> u64 {
8351 let array_index = index / 64;
8352 let bit_index = index % 64;
8353 let current = *(bitmap + array_index);
8354 if (current & (1 << bit_index)) != 0 {
8355 return 1;
8356 }
8357 return 0;
8358 }
8359 fn pmm_init(mem_size_kb: u64) {
8360 total_memory_pages = (mem_size_kb * 1024) / 4096;
8361 used_memory_pages = 0;
8362 let mut i: u64 = 0;
8363 while i < 32768 {
8364 memory_bitmap[i as usize] = 0;
8365 i = i + 1;
8366 }
8367 }
8368 fn pmm_alloc_page() -> u64 {
8369 let mut i: u64 = 0;
8370 while i < total_memory_pages {
8371 if test_bit(&memory_bitmap[0] as ptr<u64>, i) == 0 {
8372 set_bit(&memory_bitmap[0] as ptr<u64>, i);
8373 used_memory_pages = used_memory_pages + 1;
8374 return i * 4096;
8375 }
8376 i = i + 1;
8377 }
8378 return 0;
8379 }
8380 fn pmm_free_page(addr: u64) {
8381 let page_index = addr / 4096;
8382 clear_bit(&memory_bitmap[0] as ptr<u64>, page_index);
8383 used_memory_pages = used_memory_pages - 1;
8384 }
8385 fn tlb_flush_single(addr: u64) {
8386 asm {
8387 "invlpg [%0]"
8388 :
8389 : "r" (addr)
8390 : "memory"
8391 }
8392 }
8393 fn tlb_flush_all() {
8394 let mut cr3_val: u64 = 0;
8395 asm {
8396 "mov %0, cr3"
8397 "mov cr3, %0"
8398 : "=r" (cr3_val)
8399 :
8400 : "memory"
8401 }
8402 }
8403 fn read_cr3() -> u64 {
8404 let mut cr3_val: u64 = 0;
8405 asm {
8406 "mov %0, cr3"
8407 : "=r" (cr3_val)
8408 }
8409 return cr3_val;
8410 }
8411 fn write_cr3(val: u64) {
8412 asm {
8413 "mov cr3, %0"
8414 :
8415 : "r" (val)
8416 : "memory"
8417 }
8418 }
8419 fn map_page(phys: u64, virt: u64, flags: u64) {
8420 let pml4_index = (virt >> 39) & 0x1FF;
8421 let pdpt_index = (virt >> 30) & 0x1FF;
8422 let pd_index = (virt >> 21) & 0x1FF;
8423 let pt_index = (virt >> 12) & 0x1FF;
8424 let pml4 = read_cr3() as ptr<u64>;
8425 let mut pdpt_entry = *(pml4 + pml4_index);
8426
8427 if (pdpt_entry & 1) == 0 {
8428 let new_pdpt = pmm_alloc_page();
8429 *(pml4 + pml4_index) = new_pdpt | 3;
8430 pdpt_entry = new_pdpt | 3;
8431 }
8432
8433 let pdpt = (pdpt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
8434 let mut pd_entry = *(pdpt + pdpt_index);
8435
8436 if (pd_entry & 1) == 0 {
8437 let new_pd = pmm_alloc_page();
8438 *(pdpt + pdpt_index) = new_pd | 3;
8439 pd_entry = new_pd | 3;
8440 }
8441
8442 let pd = (pd_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
8443 let mut pt_entry = *(pd + pd_index);
8444
8445 if (pt_entry & 1) == 0 {
8446 let new_pt = pmm_alloc_page();
8447 *(pd + pd_index) = new_pt | 3;
8448 pt_entry = new_pt | 3;
8449 }
8450
8451 let pt = (pt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
8452 *(pt + pt_index) = (phys & 0xFFFFFFFFFFFFF000) | (flags & 0xFFF) | 1;
8453
8454 tlb_flush_single(virt);
8455 }
8456 fn unmap_page(virt: u64) {
8457 let pml4_index = (virt >> 39) & 0x1FF;
8458 let pdpt_index = (virt >> 30) & 0x1FF;
8459 let pd_index = (virt >> 21) & 0x1FF;
8460 let pt_index = (virt >> 12) & 0x1FF;
8461 let pml4 = read_cr3() as ptr<u64>;
8462 let pdpt_entry = *(pml4 + pml4_index);
8463
8464 if (pdpt_entry & 1) == 0 { return; }
8465
8466 let pdpt = (pdpt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
8467 let pd_entry = *(pdpt + pdpt_index);
8468
8469 if (pd_entry & 1) == 0 { return; }
8470
8471 let pd = (pd_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
8472 let pt_entry = *(pd + pd_index);
8473
8474 if (pt_entry & 1) == 0 { return; }
8475
8476 let pt = (pt_entry & 0xFFFFFFFFFFFFF000) as ptr<u64>;
8477 *(pt + pt_index) = 0;
8478
8479 tlb_flush_single(virt);
8480 }
8481 struct HeapBlock {
8482 size: u64,
8483 free: u64,
8484 next: u64,
8485 }
8486 let mut heap_start: u64 = 0;
8487 let mut heap_end: u64 = 0;
8488 let mut heap_head: u64 = 0;
8489 fn heap_init(start_addr: u64, initial_size: u64) {
8490 heap_start = start_addr;
8491 heap_end = start_addr + initial_size;
8492
8493 let mut current_addr = heap_start;
8494 while current_addr < heap_end {
8495 let phys = pmm_alloc_page();
8496 map_page(phys, current_addr, 3);
8497 current_addr = current_addr + 4096;
8498 }
8499
8500 heap_head = heap_start;
8501 let first_block = heap_head as ptr<HeapBlock>;
8502 (*first_block).size = initial_size - 24;
8503 (*first_block).free = 1;
8504 (*first_block).next = 0;
8505 }
8506 fn kmalloc(size: u64) -> u64 {
8507 let mut current = heap_head as ptr<HeapBlock>;
8508 let mut best_fit = 0 as ptr<HeapBlock>;
8509
8510 let mut aligned_size = size;
8511 if (aligned_size % 8) != 0 {
8512 aligned_size = aligned_size + (8 - (aligned_size % 8));
8513 }
8514
8515 while (current as u64) != 0 {
8516 if (*current).free == 1 && (*current).size >= aligned_size {
8517 if (best_fit as u64) == 0 {
8518 best_fit = current;
8519 } else {
8520 if (*current).size < (*best_fit).size {
8521 best_fit = current;
8522 }
8523 }
8524 }
8525 current = (*current).next as ptr<HeapBlock>;
8526 }
8527
8528 if (best_fit as u64) != 0 {
8529 let remaining_size = (*best_fit).size - aligned_size;
8530
8531 if remaining_size > 32 {
8532 let new_block_addr = (best_fit as u64) + 24 + aligned_size;
8533 let new_block = new_block_addr as ptr<HeapBlock>;
8534 (*new_block).size = remaining_size - 24;
8535 (*new_block).free = 1;
8536 (*new_block).next = (*best_fit).next;
8537
8538 (*best_fit).size = aligned_size;
8539 (*best_fit).next = new_block_addr;
8540 }
8541
8542 (*best_fit).free = 0;
8543 return (best_fit as u64) + 24;
8544 }
8545
8546 return 0;
8547 }
8548 fn kfree(ptr: u64) {
8549 if ptr == 0 { return; }
8550
8551 let block_addr = ptr - 24;
8552 let block = block_addr as ptr<HeapBlock>;
8553 (*block).free = 1;
8554
8555 let mut current = heap_head as ptr<HeapBlock>;
8556 while (current as u64) != 0 {
8557 if (*current).free == 1 {
8558 let next_addr = (*current).next;
8559 if next_addr != 0 {
8560 let next_block = next_addr as ptr<HeapBlock>;
8561 if (*next_block).free == 1 {
8562 (*current).size = (*current).size + 24 + (*next_block).size;
8563 (*current).next = (*next_block).next;
8564 continue;
8565 }
8566 }
8567 }
8568 current = (*current).next as ptr<HeapBlock>;
8569 }
8570 }
8571 fn wrmsr(msr: u32, val: u64) {
8572 let low = (val & 0xFFFFFFFF) as u32;
8573 let high = (val >> 32) as u32;
8574 asm {
8575 "wrmsr"
8576 :
8577 : "c" (msr), "a" (low), "d" (high)
8578 : "memory"
8579 }
8580 }
8581 fn rdmsr(msr: u32) -> u64 {
8582 let mut low: u32 = 0;
8583 let mut high: u32 = 0;
8584 asm {
8585 "rdmsr"
8586 : "=a" (low), "=d" (high)
8587 : "c" (msr)
8588 }
8589 return ((high as u64) << 32) | (low as u64);
8590 }
8591 fn syscall_init() {
8592 let star_val = (0x08 << 32) | (0x1B << 48);
8593 wrmsr(0xC0000081, star_val);
8594
8595 let lstar_val = syscall_handler_entry as u64;
8596 wrmsr(0xC0000082, lstar_val);
8597
8598 let fmask_val = 0x200;
8599 wrmsr(0xC0000084, fmask_val);
8600
8601 let efer = rdmsr(0xC0000080);
8602 wrmsr(0xC0000080, efer | 1);
8603 }
8604 fn syscall_handler_entry() {
8605 asm {
8606 "swapgs"
8607 "mov gs:[0], rsp"
8608 "mov rsp, gs:[8]"
8609
8610 "push rcx"
8611 "push r11"
8612
8613 "push rdi"
8614 "push rsi"
8615 "push rdx"
8616 "push r10"
8617 "push r8"
8618 "push r9"
8619
8620 "call syscall_dispatcher"
8621
8622 "pop r9"
8623 "pop r8"
8624 "pop r10"
8625 "pop rdx"
8626 "pop rsi"
8627 "pop rdi"
8628
8629 "pop r11"
8630 "pop rcx"
8631
8632 "mov rsp, gs:[0]"
8633 "swapgs"
8634 "sysretq"
8635 }
8636 }
8637 fn syscall_dispatcher(sys_num: u64, arg1: u64, arg2: u64, arg3: u64) -> u64 {
8638 if sys_num == 1 {
8639 return sys_write(arg1, arg2, arg3);
8640 }
8641 if sys_num == 2 {
8642 return sys_read(arg1, arg2, arg3);
8643 }
8644 if sys_num == 3 {
8645 return sys_exit(arg1);
8646 }
8647 if sys_num == 4 {
8648 return sys_mmap(arg1, arg2);
8649 }
8650 return 0;
8651 }
8652 fn sys_write(fd: u64, buf: u64, count: u64) -> u64 {
8653 if fd == 1 {
8654 let mut i: u64 = 0;
8655 let p = buf as ptr<u8>;
8656 while i < count {
8657 panic_put_char(*(p + i), 0x0F, panic_screen_cursor_x, panic_screen_cursor_y);
8658 panic_screen_cursor_x = panic_screen_cursor_x + 1;
8659 if panic_screen_cursor_x >= 80 {
8660 panic_screen_cursor_x = 0;
8661 panic_screen_cursor_y = panic_screen_cursor_y + 1;
8662 }
8663 i = i + 1;
8664 }
8665 return count;
8666 }
8667 return 0;
8668 }
8669 fn sys_read(fd: u64, buf: u64, count: u64) -> u64 {
8670 return 0;
8671 }
8672 fn sys_exit(code: u64) -> u64 {
8673 let curr_pid = current_pid;
8674 let idx = (curr_pid - 1) as usize;
8675 process_table[idx].state = 0;
8676 while true { asm { "hlt" } }
8677 return 0;
8678 }
8679 fn sys_mmap(addr: u64, len: u64) -> u64 {
8680 let pages = len / 4096 + 1;
8681 let mut i: u64 = 0;
8682 while i < pages {
8683 let phys = pmm_alloc_page();
8684 map_page(phys, addr + (i * 4096), 7);
8685 i = i + 1;
8686 }
8687 return addr;
8688 }
8689 fn switch_to_user_mode(entry_point: u64, user_stack: u64) {
8690 asm {
8691 "cli"
8692 "mov ax, 0x23"
8693 "mov ds, ax"
8694 "mov es, ax"
8695 "mov fs, ax"
8696 "mov gs, ax"
8697
8698 "push 0x23"
8699 "push %1"
8700
8701 "push 0x202"
8702
8703 "push 0x1B"
8704 "push %0"
8705
8706 "iretq"
8707 :
8708 : "r" (entry_point), "r" (user_stack)
8709 : "memory"
8710 }
8711 }
8712 fn init_user_process(code_ptr: u64, code_size: u64) {
8713 let user_stack_virt = 0x00007FFFFFFFF000;
8714 let stack_phys = pmm_alloc_page();
8715 map_page(stack_phys, user_stack_virt, 7);
8716
8717 let user_code_virt = 0x0000000000400000;
8718 let code_phys = pmm_alloc_page();
8719 map_page(code_phys, user_code_virt, 7);
8720
8721 let dest = user_code_virt as ptr<u8>;
8722 let src = code_ptr as ptr<u8>;
8723 let mut i: u64 = 0;
8724 while i < code_size {
8725 *(dest + i) = *(src + i);
8726 i = i + 1;
8727 }
8728
8729 switch_to_user_mode(user_code_virt, user_stack_virt + 4096);
8730 }
8731 fn cpuid(leaf: u32, eax: ptr<u32>, ebx: ptr<u32>, ecx: ptr<u32>, edx: ptr<u32>) {
8732 let mut a: u32 = 0;
8733 let mut b: u32 = 0;
8734 let mut c: u32 = 0;
8735 let mut d: u32 = 0;
8736 asm {
8737 "cpuid"
8738 : "=a" (a), "=b" (b), "=c" (c), "=d" (d)
8739 : "a" (leaf)
8740 }
8741 *eax = a;
8742 *ebx = b;
8743 *ecx = c;
8744 *edx = d;
8745 }
8746 fn inb(port: u16) -> u8 {
8747 let mut ret: u8 = 0;
8748 asm {
8749 "in al, dx"
8750 : "=a" (ret)
8751 : "d" (port)
8752 }
8753 return ret;
8754 }
8755 fn io_wait() {
8756 outb(0x80, 0);
8757 }
8758 fn pic_remap(offset1: u8, offset2: u8) {
8759 let a1 = inb(0x21);
8760 let a2 = inb(0xA1);
8761
8762 outb(0x20, 0x11);
8763 io_wait();
8764 outb(0xA0, 0x11);
8765 io_wait();
8766
8767 outb(0x21, offset1);
8768 io_wait();
8769 outb(0xA1, offset2);
8770 io_wait();
8771
8772 outb(0x21, 4);
8773 io_wait();
8774 outb(0xA1, 2);
8775 io_wait();
8776
8777 outb(0x21, 0x01);
8778 io_wait();
8779 outb(0xA1, 0x01);
8780 io_wait();
8781
8782 outb(0x21, a1);
8783 outb(0xA1, a2);
8784 }
8785 fn outl(port: u16, data: u32) {
8786 asm {
8787 "out dx, eax"
8788 :
8789 : "a" (data), "d" (port)
8790 }
8791 }
8792 fn inl(port: u16) -> u32 {
8793 let mut ret: u32 = 0;
8794 asm {
8795 "in eax, dx"
8796 : "=a" (ret)
8797 : "d" (port)
8798 }
8799 return ret;
8800 }
8801 fn outw(port: u16, data: u16) {
8802 asm {
8803 "out dx, ax"
8804 :
8805 : "a" (data), "d" (port)
8806 }
8807 }
8808 fn pci_config_read_word(bus: u8, slot: u8, func: u8, offset: u8) -> u16 {
8809 let lbus = bus as u32;
8810 let lslot = slot as u32;
8811 let lfunc = func as u32;
8812 let tmp = 0x80000000 | (lbus << 16) | (lslot << 11) | (lfunc << 8) | ((offset as u32) & 0xFC);
8813 outl(0xCF8, tmp);
8814 let shift = ((offset & 2) * 8) as u32;
8815 let read_val = inl(0xCFC);
8816 return ((read_val >> shift) & 0xFFFF) as u16;
8817 }
8818 fn pci_config_read_dword(bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
8819 let lbus = bus as u32;
8820 let lslot = slot as u32;
8821 let lfunc = func as u32;
8822 let tmp = 0x80000000 | (lbus << 16) | (lslot << 11) | (lfunc << 8) | ((offset as u32) & 0xFC);
8823 outl(0xCF8, tmp);
8824 return inl(0xCFC);
8825 }
8826 fn pci_check_vendor(bus: u8, slot: u8) -> u16 {
8827 return pci_config_read_word(bus, slot, 0, 0);
8828 }
8829 struct PciDevice {
8830 bus: u8,
8831 slot: u8,
8832 func: u8,
8833 vendor_id: u16,
8834 device_id: u16,
8835 class_id: u8,
8836 subclass_id: u8,
8837 prog_if: u8,
8838 rev_id: u8,
8839 bar0: u32,
8840 bar1: u32,
8841 bar2: u32,
8842 bar3: u32,
8843 bar4: u32,
8844 bar5: u32,
8845 }
8846 let mut pci_device_list: [PciDevice; 256];
8847 let mut pci_device_count: u64 = 0;
8848 fn pci_add_device(bus: u8, slot: u8, func: u8) {
8849 if pci_device_count >= 256 { return; }
8850 let vendor = pci_config_read_word(bus, slot, func, 0);
8851 if vendor == 0xFFFF { return; }
8852 let device = pci_config_read_word(bus, slot, func, 2);
8853 let class_word = pci_config_read_word(bus, slot, func, 0x0A);
8854 let class_id = (class_word >> 8) as u8;
8855 let subclass_id = (class_word & 0xFF) as u8;
8856
8857 let prog_word = pci_config_read_word(bus, slot, func, 0x08);
8858 let prog_if = (prog_word >> 8) as u8;
8859 let rev_id = (prog_word & 0xFF) as u8;
8860 let b0 = pci_config_read_dword(bus, slot, func, 0x10);
8861 let b1 = pci_config_read_dword(bus, slot, func, 0x14);
8862 let b2 = pci_config_read_dword(bus, slot, func, 0x18);
8863 let b3 = pci_config_read_dword(bus, slot, func, 0x1C);
8864 let b4 = pci_config_read_dword(bus, slot, func, 0x20);
8865 let b5 = pci_config_read_dword(bus, slot, func, 0x24);
8866 let idx = pci_device_count as usize;
8867 pci_device_list[idx].bus = bus;
8868 pci_device_list[idx].slot = slot;
8869 pci_device_list[idx].func = func;
8870 pci_device_list[idx].vendor_id = vendor;
8871 pci_device_list[idx].device_id = device;
8872 pci_device_list[idx].class_id = class_id;
8873 pci_device_list[idx].subclass_id = subclass_id;
8874 pci_device_list[idx].prog_if = prog_if;
8875 pci_device_list[idx].rev_id = rev_id;
8876 pci_device_list[idx].bar0 = b0;
8877 pci_device_list[idx].bar1 = b1;
8878 pci_device_list[idx].bar2 = b2;
8879 pci_device_list[idx].bar3 = b3;
8880 pci_device_list[idx].bar4 = b4;
8881 pci_device_list[idx].bar5 = b5;
8882 pci_device_count = pci_device_count + 1;
8883 }
8884 fn pci_scan_bus() {
8885 let mut bus: u64 = 0;
8886 while bus < 256 {
8887 let mut slot: u64 = 0;
8888 while slot < 32 {
8889 let vendor = pci_check_vendor(bus as u8, slot as u8);
8890 if vendor != 0xFFFF {
8891 let mut func: u64 = 0;
8892 while func < 8 {
8893 let f_vendor = pci_config_read_word(bus as u8, slot as u8, func as u8, 0);
8894 if f_vendor != 0xFFFF {
8895 pci_add_device(bus as u8, slot as u8, func as u8);
8896 }
8897 func = func + 1;
8898 }
8899 }
8900 slot = slot + 1;
8901 }
8902 bus = bus + 1;
8903 }
8904 }
8905 struct VfsNode {
8906 name: [u8; 64],
8907 inode: u64,
8908 size: u64,
8909 flags: u32,
8910 uid: u32,
8911 gid: u32,
8912 read_ptr: u64,
8913 write_ptr: u64,
8914 open_ptr: u64,
8915 close_ptr: u64,
8916 read_dir_ptr: u64,
8917 find_dir_ptr: u64,
8918 parent: u64,
8919 sibling: u64,
8920 child: u64,
8921 }
8922 let mut vfs_nodes: [VfsNode; 1024];
8923 let mut vfs_node_count: u64 = 0;
8924 let mut vfs_root: u64 = 0;
8925 fn vfs_init() {
8926 vfs_node_count = 1;
8927 vfs_root = 0;
8928 let root_idx = vfs_root as usize;
8929 vfs_nodes[root_idx].name[0] = 47;
8930 vfs_nodes[root_idx].name[1] = 0;
8931 vfs_nodes[root_idx].inode = 0;
8932 vfs_nodes[root_idx].size = 0;
8933 vfs_nodes[root_idx].flags = 2;
8934 vfs_nodes[root_idx].parent = 0;
8935 vfs_nodes[root_idx].sibling = 0;
8936 vfs_nodes[root_idx].child = 0;
8937 }
8938 fn strcmp(s1: ptr<u8>, s2: ptr<u8>) -> u64 {
8939 let mut i: u64 = 0;
8940 while *(s1 + i) != 0 && *(s2 + i) != 0 {
8941 if *(s1 + i) != *(s2 + i) {
8942 return 1;
8943 }
8944 i = i + 1;
8945 }
8946 if *(s1 + i) != *(s2 + i) {
8947 return 1;
8948 }
8949 return 0;
8950 }
8951 fn strcpy(dest: ptr<u8>, src: ptr<u8>) {
8952 let mut i: u64 = 0;
8953 while *(src + i) != 0 {
8954 *(dest + i) = *(src + i);
8955 i = i + 1;
8956 }
8957 *(dest + i) = 0;
8958 }
8959 fn vfs_create_file(parent_idx: u64, name: ptr<u8>, is_dir: u8) -> u64 {
8960 if vfs_node_count >= 1024 { return 0xFFFFFFFF; }
8961
8962 let new_idx = vfs_node_count;
8963 let n_idx = new_idx as usize;
8964 let p_idx = parent_idx as usize;
8965
8966 strcpy(&vfs_nodes[n_idx].name[0] as ptr<u8>, name);
8967 vfs_nodes[n_idx].inode = new_idx;
8968 vfs_nodes[n_idx].size = 0;
8969 if is_dir == 1 {
8970 vfs_nodes[n_idx].flags = 2;
8971 } else {
8972 vfs_nodes[n_idx].flags = 1;
8973 }
8974 vfs_nodes[n_idx].parent = parent_idx;
8975 vfs_nodes[n_idx].sibling = vfs_nodes[p_idx].child;
8976 vfs_nodes[n_idx].child = 0;
8977
8978 vfs_nodes[p_idx].child = new_idx;
8979 vfs_node_count = vfs_node_count + 1;
8980
8981 return new_idx;
8982 }
8983 fn vfs_find_child(parent_idx: u64, name: ptr<u8>) -> u64 {
8984 let p_idx = parent_idx as usize;
8985 let mut curr_idx = vfs_nodes[p_idx].child;
8986
8987 while curr_idx != 0 {
8988 let c_idx = curr_idx as usize;
8989 if strcmp(&vfs_nodes[c_idx].name[0] as ptr<u8>, name) == 0 {
8990 return curr_idx;
8991 }
8992 curr_idx = vfs_nodes[c_idx].sibling;
8993 }
8994 return 0xFFFFFFFF;
8995 }
8996 struct FileDescriptor {
8997 node_idx: u64,
8998 offset: u64,
8999 flags: u32,
9000 used: u8,
9001 }
9002 let mut fd_table: [FileDescriptor; 256];
9003 fn fd_init() {
9004 let mut i: u64 = 0;
9005 while i < 256 {
9006 fd_table[i as usize].used = 0;
9007 i = i + 1;
9008 }
9009 }
9010 fn sys_open(path: ptr<u8>, flags: u32) -> u64 {
9011 let mut i: u64 = 0;
9012 let mut fd_idx: u64 = 0xFFFFFFFF;
9013 while i < 256 {
9014 if fd_table[i as usize].used == 0 {
9015 fd_idx = i;
9016 break;
9017 }
9018 i = i + 1;
9019 }
9020 if fd_idx == 0xFFFFFFFF { return 0xFFFFFFFF; }
9021
9022 let node_idx = vfs_find_child(vfs_root, path);
9023 if node_idx == 0xFFFFFFFF {
9024 if (flags & 0x40) != 0 {
9025 let new_node = vfs_create_file(vfs_root, path, 0);
9026 if new_node == 0xFFFFFFFF { return 0xFFFFFFFF; }
9027 fd_table[fd_idx as usize].node_idx = new_node;
9028 fd_table[fd_idx as usize].offset = 0;
9029 fd_table[fd_idx as usize].flags = flags;
9030 fd_table[fd_idx as usize].used = 1;
9031 return fd_idx;
9032 }
9033 return 0xFFFFFFFF;
9034 }
9035
9036 fd_table[fd_idx as usize].node_idx = node_idx;
9037 fd_table[fd_idx as usize].offset = 0;
9038 fd_table[fd_idx as usize].flags = flags;
9039 fd_table[fd_idx as usize].used = 1;
9040 return fd_idx;
9041 }
9042 struct AhciHbaPort {
9043 clb: u32,
9044 clbu: u32,
9045 fb: u32,
9046 fbu: u32,
9047 is: u32,
9048 ie: u32,
9049 cmd: u32,
9050 rsv0: u32,
9051 tfd: u32,
9052 sig: u32,
9053 ssts: u32,
9054 sctl: u32,
9055 serr: u32,
9056 sact: u32,
9057 ci: u32,
9058 sntf: u32,
9059 fbs: u32,
9060 rsv1: [u32; 11],
9061 vendor: [u32; 4],
9062 }
9063 struct AhciHbaMem {
9064 cap: u32,
9065 ghc: u32,
9066 is: u32,
9067 pi: u32,
9068 vs: u32,
9069 ccc_ctl: u32,
9070 ccc_pts: u32,
9071 em_loc: u32,
9072 em_ctl: u32,
9073 cap2: u32,
9074 bohc: u32,
9075 rsv: [u8; 116],
9076 vendor: [u8; 96],
9077 ports: [AhciHbaPort; 32],
9078 }
9079 fn ahci_check_type(port: ptr<AhciHbaPort>) -> u32 {
9080 let ssts = (*port).ssts;
9081 let ipm = (ssts >> 8) & 0x0F;
9082 let det = ssts & 0x0F;
9083 if det != 3 { return 0; }
9084 if ipm != 1 { return 0; }
9085 let sig = (*port).sig;
9086 if sig == 0x00000101 { return 1; }
9087 if sig == 0xEB140101 { return 2; }
9088 if sig == 0x96690101 { return 3; }
9089 if sig == 0xC33C0101 { return 4; }
9090 return 0;
9091 }
9092 let mut ahci_base_address: u64 = 0;
9093 fn ahci_init(pci_bus: u8, pci_slot: u8, pci_func: u8) {
9094 let bar5_val = pci_config_read_dword(pci_bus, pci_slot, pci_func, 0x24);
9095 ahci_base_address = (bar5_val & 0xFFFFFFF0) as u64;
9096 let hba = ahci_base_address as ptr<AhciHbaMem>;
9097 let pi = (*hba).pi;
9098 let mut i: u32 = 0;
9099 while i < 32 {
9100 if (pi & (1 << i)) != 0 {
9101 let port_ptr = &(*hba).ports[i as usize] as ptr<AhciHbaPort>;
9102 let ptype = ahci_check_type(port_ptr);
9103 }
9104 i = i + 1;
9105 }
9106 }
9107 fn rtl8139_init(bus: u8, slot: u8, func: u8) {
9108 let bar0 = pci_config_read_dword(bus, slot, func, 0x10);
9109 let io_base = (bar0 & 0xFFFFFFFC) as u16;
9110 outb(io_base + 0x52, 0x00);
9111 outb(io_base + 0x37, 0x10);
9112 let mut i: u16 = 0;
9113 while i < 1000 {
9114 if (inb(io_base + 0x37) & 0x10) == 0 {
9115 break;
9116 }
9117 i = i + 1;
9118 }
9119 let rx_buffer = pmm_alloc_page();
9120 let rx_buffer_phys = rx_buffer & 0xFFFFFFFF;
9121 outl(io_base + 0x30, rx_buffer_phys as u32);
9122 outw(io_base + 0x3C, 0x0005);
9123 outl(io_base + 0x44, 0x0000000F | 0x00000080);
9124 outb(io_base + 0x37, 0x0C);
9125 }
9126 fn pci_driver_match() {
9127 let mut i: u64 = 0;
9128 while i < pci_device_count {
9129 let dev = &pci_device_list[i as usize] as ptr<PciDevice>;
9130 if (*dev).class_id == 0x01 && (*dev).subclass_id == 0x06 {
9131 if (*dev).prog_if == 0x01 {
9132 ahci_init((*dev).bus, (*dev).slot, (*dev).func);
9133 }
9134 }
9135 if (*dev).vendor_id == 0x10EC && (*dev).device_id == 0x8139 {
9136 rtl8139_init((*dev).bus, (*dev).slot, (*dev).func);
9137 }
9138 i = i + 1;
9139 }
9140 }
9141 let keymap_lower: [u8; 128] = [
9142 0, 27, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 8,
9143 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 91, 93, 10,
9144 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59, 39, 96,
9145 0, 92, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0,
9146 42, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9147 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0,
9148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
9150 ];
9151 let keymap_upper: [u8; 128] = [
9152 0, 27, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 8,
9153 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 123, 125, 10,
9154 0, 65, 83, 68, 70, 71, 72, 74, 75, 76, 58, 34, 126,
9155 0, 124, 90, 88, 67, 86, 66, 78, 77, 60, 62, 63, 0,
9156 42, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9157 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0,
9158 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
9160 ];
9161 let mut kbd_shift_active: u8 = 0;
9162 let mut kbd_caps_active: u8 = 0;
9163 let mut shell_buffer: [u8; 256];
9164 let mut shell_idx: u64 = 0;
9165 let mut shell_active: u8 = 0;
9166 fn kbd_init() {
9167 let mut status = inb(0x64);
9168 while (status & 2) != 0 {
9169 status = inb(0x64);
9170 }
9171 outb(0x64, 0xAD);
9172 outb(0x64, 0xA7);
9173 let temp = inb(0x60);
9174 outb(0x64, 0xAE);
9175 }
9176 fn kbd_handler(state: ptr<CpuState>) {
9177 let status = inb(0x64);
9178 if (status & 1) != 0 {
9179 let scancode = inb(0x60);
9180
9181 if scancode == 0x2A || scancode == 0x36 {
9182 kbd_shift_active = 1;
9183 } else if scancode == 0xAA || scancode == 0xB6 {
9184 kbd_shift_active = 0;
9185 } else if scancode == 0x3A {
9186 if kbd_caps_active == 0 {
9187 kbd_caps_active = 1;
9188 } else {
9189 kbd_caps_active = 0;
9190 }
9191 } else if (scancode & 0x80) == 0 {
9192 let mut ascii: u8 = 0;
9193 let mut use_upper = kbd_shift_active;
9194
9195 if kbd_caps_active == 1 {
9196 let base_char = keymap_lower[scancode as usize];
9197 if base_char >= 97 && base_char <= 122 {
9198 if kbd_shift_active == 1 {
9199 use_upper = 0;
9200 } else {
9201 use_upper = 1;
9202 }
9203 }
9204 }
9205
9206 if use_upper == 1 {
9207 ascii = keymap_upper[scancode as usize];
9208 } else {
9209 ascii = keymap_lower[scancode as usize];
9210 }
9211
9212 if ascii != 0 && shell_active == 1 {
9213 shell_process_key(ascii);
9214 }
9215 }
9216 }
9217 outb(0x20, 0x20);
9218 }
9219 fn shell_print_prompt() {
9220 panic_print_string("root@w-os # " as ptr<u8>, 0x0A);
9221 }
9222 fn shell_init() {
9223 shell_idx = 0;
9224 shell_active = 1;
9225 let mut i: u64 = 0;
9226 while i < 256 {
9227 shell_buffer[i as usize] = 0;
9228 i = i + 1;
9229 }
9230 panic_clear_screen(0x0F);
9231 panic_print_string("W Operating System - Core Shell\n" as ptr<u8>, 0x0B);
9232 panic_print_string("Type 'help' for a list of commands.\n\n" as ptr<u8>, 0x07);
9233 shell_print_prompt();
9234 }
9235 fn shell_execute() {
9236 panic_print_string("\n" as ptr<u8>, 0x07);
9237 if shell_idx == 0 {
9238 shell_print_prompt();
9239 return;
9240 }
9241
9242 shell_buffer[shell_idx as usize] = 0;
9243 let cmd_ptr = &shell_buffer[0] as ptr<u8>;
9244
9245 if strcmp(cmd_ptr, "help" as ptr<u8>) == 0 {
9246 panic_print_string("Available commands:\n" as ptr<u8>, 0x0F);
9247 panic_print_string(" help - Show this message\n" as ptr<u8>, 0x07);
9248 panic_print_string(" clear - Clear the screen\n" as ptr<u8>, 0x07);
9249 panic_print_string(" uname - Show system information\n" as ptr<u8>, 0x07);
9250 panic_print_string(" lspci - List PCI devices\n" as ptr<u8>, 0x07);
9251 } else if strcmp(cmd_ptr, "clear" as ptr<u8>) == 0 {
9252 panic_clear_screen(0x0F);
9253 } else if strcmp(cmd_ptr, "uname" as ptr<u8>) == 0 {
9254 panic_print_string("W Kernel 0.0.1 beta - x86_64\n" as ptr<u8>, 0x0E);
9255 } else if strcmp(cmd_ptr, "lspci" as ptr<u8>) == 0 {
9256 let mut i: u64 = 0;
9257 while i < pci_device_count {
9258 let dev = &pci_device_list[i as usize] as ptr<PciDevice>;
9259 panic_print_string("Bus " as ptr<u8>, 0x07);
9260 panic_print_hex((*dev).bus as u64, 0x07);
9261 panic_print_string(" Slot " as ptr<u8>, 0x07);
9262 panic_print_hex((*dev).slot as u64, 0x07);
9263 panic_print_string(" - Vendor: " as ptr<u8>, 0x07);
9264 panic_print_hex((*dev).vendor_id as u64, 0x0A);
9265 panic_print_string(" Device: " as ptr<u8>, 0x07);
9266 panic_print_hex((*dev).device_id as u64, 0x0B);
9267 panic_print_string("\n" as ptr<u8>, 0x07);
9268 i = i + 1;
9269 }
9270 } else {
9271 panic_print_string("Unknown command: " as ptr<u8>, 0x0C);
9272 panic_print_string(cmd_ptr, 0x0C);
9273 panic_print_string("\n" as ptr<u8>, 0x07);
9274 }
9275
9276 shell_idx = 0;
9277 shell_print_prompt();
9278 }
9279 fn shell_process_key(c: u8) {
9280 if c == 10 {
9281 shell_execute();
9282 } else if c == 8 {
9283 if shell_idx > 0 {
9284 shell_idx = shell_idx - 1;
9285 shell_buffer[shell_idx as usize] = 0;
9286 if panic_screen_cursor_x > 0 {
9287 panic_screen_cursor_x = panic_screen_cursor_x - 1;
9288 } else if panic_screen_cursor_y > 0 {
9289 panic_screen_cursor_y = panic_screen_cursor_y - 1;
9290 panic_screen_cursor_x = 79;
9291 }
9292 panic_put_char(32, 0x0F, panic_screen_cursor_x, panic_screen_cursor_y);
9293 }
9294 } else {
9295 if shell_idx < 255 {
9296 shell_buffer[shell_idx as usize] = c;
9297 shell_idx = shell_idx + 1;
9298 let mut color_code: u8 = 0x0F;
9299 panic_put_char(c, color_code, panic_screen_cursor_x, panic_screen_cursor_y);
9300 panic_screen_cursor_x = panic_screen_cursor_x + 1;
9301 if panic_screen_cursor_x >= 80 {
9302 panic_screen_cursor_x = 0;
9303 panic_screen_cursor_y = panic_screen_cursor_y + 1;
9304 if panic_screen_cursor_y >= 25 {
9305 panic_screen_cursor_y = 24;
9306 }
9307 }
9308 }
9309 }
9310 }
9311 struct BootSectorFat32 {
9312 jmp: [u8; 3],
9313 oem_name: [u8; 8],
9314 bytes_per_sector: u16,
9315 sectors_per_cluster: u8,
9316 reserved_sectors: u16,
9317 fat_count: u8,
9318 root_dir_entries: u16,
9319 total_sectors_16: u16,
9320 media_descriptor: u8,
9321 sectors_per_fat_16: u16,
9322 sectors_per_track: u16,
9323 head_count: u16,
9324 hidden_sectors: u32,
9325 total_sectors_32: u32,
9326 sectors_per_fat_32: u32,
9327 ext_flags: u16,
9328 fs_version: u16,
9329 root_cluster: u32,
9330 fs_info_sector: u16,
9331 backup_boot_sector: u16,
9332 reserved: [u8; 12],
9333 drive_number: u8,
9334 reserved1: u8,
9335 boot_signature: u8,
9336 volume_id: u32,
9337 volume_label: [u8; 11],
9338 fs_type: [u8; 8],
9339 }
9340 struct Fat32DirEntry {
9341 name: [u8; 11],
9342 attr: u8,
9343 nt_res: u8,
9344 crt_time_tenth: u8,
9345 crt_time: u16,
9346 crt_date: u16,
9347 last_access_date: u16,
9348 cluster_high: u16,
9349 write_time: u16,
9350 write_date: u16,
9351 cluster_low: u16,
9352 file_size: u32,
9353 }
9354 let mut fat32_lba_start: u32 = 0;
9355 let mut fat32_root_cluster: u32 = 0;
9356 let mut fat32_sectors_per_cluster: u32 = 0;
9357 let mut fat32_bytes_per_cluster: u32 = 0;
9358 let mut fat32_fat_start: u32 = 0;
9359 let mut fat32_data_start: u32 = 0;
9360 fn fat32_init(lba: u32, buffer: ptr<u8>) {
9361 let bs = buffer as ptr<BootSectorFat32>;
9362 fat32_lba_start = lba;
9363 fat32_sectors_per_cluster = (*bs).sectors_per_cluster as u32;
9364 fat32_bytes_per_cluster = fat32_sectors_per_cluster * ((*bs).bytes_per_sector as u32);
9365 fat32_fat_start = lba + ((*bs).reserved_sectors as u32);
9366 let fat_size = (*bs).sectors_per_fat_32;
9367 let fat_count = (*bs).fat_count as u32;
9368 fat32_data_start = fat32_fat_start + (fat_size * fat_count);
9369 fat32_root_cluster = (*bs).root_cluster;
9370 }
9371 fn fat32_cluster_to_lba(cluster: u32) -> u32 {
9372 if cluster < 2 { return 0; }
9373 return fat32_data_start + ((cluster - 2) * fat32_sectors_per_cluster);
9374 }
9375 fn fat32_compare_name(entry_name: ptr<u8>, target: ptr<u8>) -> u32 {
9376 let mut i: u64 = 0;
9377 while i < 11 {
9378 if *(target + i) == 0 {
9379 if *(entry_name + i) == 32 {
9380 let mut j = i;
9381 let mut all_space = 1;
9382 while j < 11 {
9383 if *(entry_name + j) != 32 {
9384 all_space = 0;
9385 break;
9386 }
9387 j = j + 1;
9388 }
9389 if all_space == 1 { return 1; }
9390 }
9391 return 0;
9392 }
9393 if *(entry_name + i) != *(target + i) {
9394 return 0;
9395 }
9396 i = i + 1;
9397 }
9398 if *(target + 11) == 0 { return 1; }
9399 return 0;
9400 }
9401 struct WefHeader {
9402 magic: u32,
9403 arch: u8,
9404 os_abi: u8,
9405 type_id: u16,
9406 machine: u16,
9407 version: u32,
9408 entry: u64,
9409 ph_off: u64,
9410 sh_off: u64,
9411 flags: u32,
9412 eh_size: u16,
9413 ph_ent_size: u16,
9414 ph_num: u16,
9415 sh_ent_size: u16,
9416 sh_num: u16,
9417 sh_str_ndx: u16,
9418 }
9419 struct WefProgramHeader {
9420 type_id: u32,
9421 flags: u32,
9422 offset: u64,
9423 vaddr: u64,
9424 paddr: u64,
9425 filesz: u64,
9426 memsz: u64,
9427 align: u64,
9428 }
9429 fn wef_check_magic(header: ptr<WefHeader>) -> u32 {
9430 let m = (*header).magic;
9431 if m == 0x4645577F {
9432 return 1;
9433 }
9434 return 0;
9435 }
9436 fn sys_yield() {
9437 asm {
9438 "int 0x20"
9439 }
9440 }
9441 fn sys_wait_pid(pid: u64) {
9442 let mut status: u8 = 1;
9443 while status == 1 {
9444 let mut i: u64 = 0;
9445 let mut found = 0;
9446 while i < 256 {
9447 if process_table[i as usize].pid == pid {
9448 status = process_table[i as usize].state;
9449 found = 1;
9450 break;
9451 }
9452 i = i + 1;
9453 }
9454 if found == 0 { break; }
9455 sys_yield();
9456 }
9457 }
9458 fn wef_load_segment(ph: ptr<WefProgramHeader>, file_base: u64, cr3_val: u64) {
9459 if (*ph).type_id != 1 { return; }
9460 if (*ph).memsz == 0 { return; }
9461 let vaddr_start = (*ph).vaddr;
9462 let memsz = (*ph).memsz;
9463 let filesz = (*ph).filesz;
9464 let offset = (*ph).offset;
9465 let page_count = (memsz + 4095) / 4096;
9466 let mut i: u64 = 0;
9467
9468 let current_cr3 = read_cr3();
9469 write_cr3(cr3_val);
9470 while i < page_count {
9471 let phys_page = pmm_alloc_page();
9472 let virt_page = (vaddr_start & 0xFFFFFFFFFFFFF000) + (i * 4096);
9473 let mut flags: u64 = 5;
9474 if ((*ph).flags & 2) != 0 {
9475 flags = flags | 2;
9476 }
9477 map_page(phys_page, virt_page, flags);
9478 i = i + 1;
9479 }
9480 let dest = vaddr_start as ptr<u8>;
9481 let src = (file_base + offset) as ptr<u8>;
9482
9483 let mut j: u64 = 0;
9484 while j < filesz {
9485 *(dest + j) = *(src + j);
9486 j = j + 1;
9487 }
9488
9489 while j < memsz {
9490 *(dest + j) = 0;
9491 j = j + 1;
9492 }
9493
9494 write_cr3(current_cr3);
9495 }
9496 fn process_exec_wef(file_buffer: u64) -> u64 {
9497 let header = file_buffer as ptr<WefHeader>;
9498 if wef_check_magic(header) == 0 {
9499 return 0;
9500 }
9501 let pml4_phys = pmm_alloc_page();
9502
9503 let kernel_pml4 = read_cr3() as ptr<u64>;
9504 let new_pml4 = pml4_phys as ptr<u64>;
9505
9506 let mut idx: u64 = 256;
9507 while idx < 512 {
9508 *(new_pml4 + idx) = *(kernel_pml4 + idx);
9509 idx = idx + 1;
9510 }
9511 // --- Düzeltilmiş Yükleme ve Yığın Haritalama ---
9512 fn load_process_image(file_buffer: u64, header: ptr<WefHeader>, pml4_phys: u64) -> u64 {
9513 let ph_base = file_buffer + (*header).ph_off;
9514 let ph_count = (*header).ph_num as u64;
9515 let ph_size = (*header).ph_ent_size as u64;
9516
9517 let mut i: u64 = 0;
9518 while i < ph_count {
9519 let ph_ptr = (ph_base + (i * ph_size)) as ptr<WefProgramHeader>;
9520 wef_load_segment(ph_ptr, file_buffer, pml4_phys);
9521 i = i + 1;
9522 }
9523
9524 // Yığın: 0x00007FFFFFFFF000 adresine 1 sayfa tahsis et (Aşağı doğru büyür)
9525 let user_stack_virt = 0x00007FFFFFFFE000;
9526 let stack_phys = pmm_alloc_page();
9527 memset(stack_phys as ptr<u8>, 0, 4096);
9528
9529 // Geçici CR3 değişiminde Triple Fault yaşamamak için çekirdek alanı aktif kalmalıdır
9530 let current_cr3 = read_cr3();
9531 write_cr3(pml4_phys);
9532 map_page(stack_phys, user_stack_virt, 7); // Present | Writable | User
9533 write_cr3(current_cr3);
9534
9535 let entry_point = (*header).entry;
9536 // Yığın tepesi: Taban + 4096 (x86_64 ABI gereği 16-bayt hizalı olmalı)
9537 let stack_top = user_stack_virt + 4096;
9538 let new_pid = process_create(entry_point, stack_top, pml4_phys);
9539
9540 return new_pid;
9541 }
9542
9543 // --- Düzeltilmiş sys_fork ---
9544 fn sys_fork() -> u64 {
9545 let curr_pid = current_pid;
9546 if curr_pid == 0 { return 0; }
9547
9548 let parent_idx = (curr_pid - 1) as usize;
9549 let parent_cr3 = process_table[parent_idx].cr3;
9550
9551 let child_cr3 = pmm_alloc_page();
9552 if child_cr3 == 0 { return 0; } // Bellek yetersizliği kontrolü
9553
9554 // Yeni sayfa tablosunu sıfırla
9555 memset(child_cr3 as ptr<u8>, 0, 4096);
9556
9557 let p_pml4 = parent_cr3 as ptr<u64>;
9558 let c_pml4 = child_cr3 as ptr<u64>;
9559
9560 // 1. Çekirdek Alanını Paylaş (Higher-Half: 256..512)
9561 let mut k: u64 = 256;
9562 while k < 512 {
9563 *(c_pml4 + k) = *(p_pml4 + k);
9564 k = k + 1;
9565 }
9566
9567 // 2. Kullanıcı Alanını Klonla (Lower-Half: 0..256)
9568 // Gerçek fork için sayfalar klonlanmalı veya CoW (Copy-on-Write) kurulmalıdır.
9569 // Başlangıç için mevcut kullanıcı PML4 girdileri kopyalanır:
9570 let mut u: u64 = 0;
9571 while u < 256 {
9572 if *(p_pml4 + u) != 0 {
9573 // Tam sayfa kopyalama / alt PML4 kopyalama burada devreye girmelidir
9574 *(c_pml4 + u) = *(p_pml4 + u);
9575 }
9576 u = u + 1;
9577 }
9578
9579 let child_pid = process_create(
9580 process_table[parent_idx].rip,
9581 process_table[parent_idx].rsp,
9582 child_cr3
9583 );
9584
9585 if child_pid == 0 {
9586 pmm_free_page(child_cr3);
9587 return 0;
9588 }
9589
9590 return child_pid;
9591 }
9592
9593 // --- Düzeltilmiş Çekirdek İş Parçacığı ---
9594 fn kthread_create(entry: u64, stack_size: u64) -> u64 {
9595 let stack_base = kmalloc(stack_size);
9596 if stack_base == 0 { return 0; }
9597
9598 // x86_64 yığın aşağı büyür ve 16-bayt hizalı olmalıdır
9599 let stack_top = (stack_base + stack_size) & !0xFull;
9600 let cr3 = read_cr3();
9601
9602 let pid = process_create(entry, stack_top, cr3);
9603 if pid == 0 {
9604 kfree(stack_base);
9605 return 0;
9606 }
9607
9608 let idx = (pid - 1) as usize;
9609 process_table[idx].state = 2; // Ready
9610
9611 return pid;
9612 }
9613
9614 // --- Düzeltilmiş Donanım Saati (RTC) ve Zamanlayıcı ---
9615 let mut uptime_seconds: u64 = 0;
9616 let mut uptime_ms: u64 = 0;
9617 let mut timer_lock: Spinlock;
9618
9619 fn rtc_read(reg: u8) -> u8 {
9620 // Port 0x70 üzerinde NMI durumunu korumak ve güncellemeyi beklemek
9621 // Status Register A (0x0A) bit 7: Update-In-Progress kontrolü
9622 if reg != 0x0A {
9623 while (rtc_read(0x0A) & 0x80) != 0 {
9624 cpu_pause();
9625 }
9626 }
9627
9628 // NMI'ı devrede tutmak için 0x80 maskesi uygulanabilir (donanıma bağlı)
9629 outb(0x70, reg & 0x7F);
9630 return inb(0x71);
9631 }
9632
9633 fn timer_update_uptime() {
9634 spin_lock(&timer_lock);
9635 uptime_ms = uptime_ms + 1;
9636 if uptime_ms >= 1000 {
9637 uptime_ms = 0;
9638 uptime_seconds = uptime_seconds + 1;
9639 }
9640 spin_unlock(&timer_lock);
9641 }

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