os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

kernel.x86_64.om (82479B)


      1 func syscall(n: int, a1: int, a2: int, a3: int, a4: int, a5: int, a6: int): int;
      2 
      3 func inb(a: int): int;
      4 func outb(a: int, x: int);
      5 
      6 func inw(a: int): int;
      7 func outw(a: int, x: int);
      8 
      9 func ind(a: int): int;
     10 func outd(a: int, x: int);
     11 
     12 func rdmsr(r: int): int;
     13 func wrmsr(r: int, x: int);
     14 
     15 func rdcr2(): int;
     16 func rdcr3(): int;
     17 func wrcr3(x: int);
     18 func rdcr4(): int;
     19 
     20 func lgdt(base: *int, size: int);
     21 func lidt(base: *int, size: int);
     22 func lldt(s: int);
     23 func ltr(s: int);
     24 func lseg(cs: int, ds: int);
     25 
     26 func hlt();
     27 
     28 func cli();
     29 func sti();
     30 func rdflags(): int;
     31 func wrflags(x: int);
     32 
     33 func invlpg(x: int);
     34 
     35 func _isr0();
     36 func _ssr0();
     37 
     38 func _include(name: *byte, len: *int): *byte;
     39 func _rdrand(): int;
     40 
     41 func _rgs(x: int): int;
     42 
     43 struct regs {
     44 	rax: int;	// 0
     45 	rcx: int;	// 8
     46 	rdx: int;	// 16
     47 	rbx: int;	// 24
     48 	rsp: int;	// 32
     49 	rbp: int;	// 40
     50 	rsi: int;	// 48
     51 	rdi: int;	// 56
     52 	r8: int;	// 64
     53 	r9: int;	// 72
     54 	r10: int;	// 80
     55 	r11: int;	// 88
     56 	r12: int;	// 96
     57 	r13: int;	// 104
     58 	r14: int;	// 112
     59 	r15: int;	// 120
     60 	rip: int;	// 128
     61 	rflags: int;	// 136
     62 	cs: int;	// 144
     63 	ss: int;	// 152
     64 	trap: int;	// 160
     65 	err: int;	// 168
     66 			// 176
     67 }
     68 
     69 func taskswitch(save_regs: *regs, load_regs: *regs);
     70 
     71 func _r32(p: *byte): int;
     72 func _w32(p: *byte, x: int): int;
     73 
     74 func _r16(p: *byte): int;
     75 func _w16(p: *byte, x: int): int;
     76 
     77 enum {
     78 	IO_PIC1 = 0x20,
     79 	IO_PIC2 = 0xa0,
     80 	IO_PIT = 0x40,
     81 }
     82 
     83 func gdt_tss(s: *int, base: int, size: int, access: int, flags: int) {
     84 	s[0] = (((base & ~0xffff) << 32)
     85 		+ ((flags & 0xf) << 52)
     86 		+ (((size - 1) & 0xf0000) << 32)
     87 		+ ((access & 0xff) << 40)
     88 		+ ((base & 0xff0000) << 16)
     89 		+ ((base & 0xffff) << 16)
     90 		+ ((size - 1) & 0xffff));
     91 	s[1] = base >> 32;
     92 }
     93 
     94 func idt_gate(s: *int, offset: int, dpl: int, ist: int) {
     95 	s[0] = (((offset & ~0xffff) << 32)
     96 		+ (1 << 47)
     97 		+ ((dpl & 3) << 45)
     98 		+ (0x0e << 40)
     99 		+ ((ist & 7) << 32)
    100 		+ (8 << 16)
    101 		+ (offset & 0xffff));
    102 	s[1] = offset >> 32;
    103 }
    104 
    105 func bzero(s: *byte, size: int) {
    106 	var i: int;
    107 	i = 0;
    108 	loop {
    109 		if i == size {
    110 			break;
    111 		}
    112 		s[i] = 0 as byte;
    113 		i = i + 1;
    114 	}
    115 }
    116 
    117 func panic(r: *regs) {
    118 	var i: int;
    119 	var sp: int;
    120 
    121 	cli();
    122 
    123 	//     ---------------- ---------------- ---------------- ---------------- ----
    124 	kputs("rax              rcx              rdx              rbx\n");
    125 	kputh(r.rax);
    126 	kputc(' ');
    127 	kputh(r.rcx);
    128 	kputc(' ');
    129 	kputh(r.rdx);
    130 	kputc(' ');
    131 	kputh(r.rbx);
    132 	kputc('\n');
    133 
    134 	//     ---------------- ---------------- ---------------- ---------------- ----
    135 	kputs("rsi              rdi              r8               r9\n");
    136 	kputh(r.rsi);
    137 	kputc(' ');
    138 	kputh(r.rdi);
    139 	kputc(' ');
    140 	kputh(r.r8);
    141 	kputc(' ');
    142 	kputh(r.r9);
    143 	kputc('\n');
    144 
    145 	//     ---------------- ---------------- ---------------- ---------------- ----
    146 	kputs("r10              r11              r12              r13\n");
    147 	kputh(r.r10);
    148 	kputc(' ');
    149 	kputh(r.r11);
    150 	kputc(' ');
    151 	kputh(r.r12);
    152 	kputc(' ');
    153 	kputh(r.r13);
    154 	kputc('\n');
    155 
    156 	//     ---------------- ---------------- ---------------- ---------------- ----
    157 	kputs("r14              r15              rbp              rsp              ss\n");
    158 	kputh(r.r14);
    159 	kputc(' ');
    160 	kputh(r.r15);
    161 	kputc(' ');
    162 	kputh(r.rbp);
    163 	kputc(' ');
    164 	kputh(r.rsp);
    165 	kputc(' ');
    166 	kputh16(r.ss);
    167 	kputc('\n');
    168 
    169 	//     ---------------- ---------------- ---------------- ---------------- ----
    170 	kputs("rip              rflags           cr2              cr4              cs\n");
    171 	kputh(r.rip);
    172 	kputc(' ');
    173 	kputh(r.rflags);
    174 	kputc(' ');
    175 	kputh(rdcr2());
    176 	kputc(' ');
    177 	kputh(rdcr4());
    178 	kputc(' ');
    179 	kputh16(r.cs);
    180 	kputc('\n');
    181 
    182 	kputs("backtrace:\n");
    183 
    184 	i = 0;
    185 	sp = r.rbp;
    186 	loop {
    187 		kputh(sp);
    188 		kputc(' ');
    189 
    190 		if sp >= 0 {
    191 			break;
    192 		}
    193 
    194 		sp = sp as *int[0];
    195 
    196 		i = i + 1;
    197 		if i == 8 {
    198 			break;
    199 		}
    200 
    201 		if i & 3 == 0 {
    202 			kputc('\n');
    203 		}
    204 	}
    205 
    206 	kputc('\n');
    207 
    208 	loop {
    209 		hlt();
    210 	}
    211 }
    212 
    213 func _isr(r: *regs) {
    214 	var global: *global;
    215 	global = g();
    216 
    217 	if (r.trap < 32) {
    218 		kputs("EX ");
    219 		kputd(r.trap);
    220 		kputs(":");
    221 		kputd(r.err);
    222 		kputs("\n");
    223 		panic(r);
    224 		loop {
    225 			hlt();
    226 		}
    227 	} else if (r.trap == 32) {
    228 		tick(r);
    229 		outb(IO_PIC1, 0x20);
    230 	} else if (global.lapic) {
    231 		if (r.trap == 33) {
    232 			isr_realtek();
    233 		} else if (r.trap == 34) {
    234 			isr_ahci();
    235 		}
    236 		// apic end of interrupt
    237 		_w32(&global.lapic[0xb0], 0);
    238 	}
    239 }
    240 
    241 func fill_idt(s: *int) {
    242 	var i: int;
    243 	var ist: int;
    244 	loop {
    245 		if i == 256 {
    246 			break;
    247 		}
    248 		if i == 2 {
    249 			ist = 2;
    250 		} else {
    251 			ist = 1;
    252 		}
    253 		idt_gate(&s[i * 2], _isr0 as int + i * 16, 0, ist);
    254 		i = i + 1;
    255 	}
    256 }
    257 
    258 func memcmp(a: *byte, b: *byte, n: int): int {
    259 	var i: int;
    260 
    261 	i = 0;
    262 
    263 	loop {
    264 		if i == n {
    265 			return 0;
    266 		}
    267 
    268 		if (a[i] > b[i]) {
    269 			return 1;
    270 		}
    271 
    272 		if (a[i] < b[i]) {
    273 			return -1;
    274 		}
    275 
    276 		i = i + 1;
    277 	}
    278 }
    279 
    280 func bytesum(a: *byte, n: int): int {
    281 	var i: int;
    282 	var x: byte;
    283 
    284 	i = 0;
    285 	x = 0 as byte;
    286 	loop {
    287 		if i == n {
    288 			return x as int;
    289 		}
    290 
    291 		x = x + a[i];
    292 
    293 		i = i + 1;
    294 	}
    295 }
    296 
    297 func ptov(p: int): *byte {
    298 	if p < (1 << 30) {
    299 		return (p - 0x80000000) as *byte;
    300 	} else {
    301 		return (p + (-1 << 47)) as *byte;
    302 	}
    303 }
    304 
    305 func vtop(v: *byte): int {
    306 	var va: int;
    307 	va = v as int;
    308 
    309 	// direct map
    310 	if va >= (-1 << 47) && va < (-1 << 46) {
    311 		return va & ((1 << 46) - 1);
    312 	}
    313 
    314 	// -2G to -1G is mapped to 0 - 1G
    315 	if va >= (-1 << 31) && va < (-1 << 30) {
    316 		return va & ((1 << 30) - 1);
    317 	}
    318 
    319 	kdie("BAD VA");
    320 	return 0;
    321 }
    322 
    323 func acpi_len(p: int): int {
    324 	if p == 0 {
    325 		return 0;
    326 	}
    327 	return _r32((ptov(p) as int + 4) as *byte);
    328 }
    329 
    330 func valid_table(p: int, sig: *byte): int {
    331 	var len: int;
    332 	var v: *byte;
    333 
    334 	v = ptov(p);
    335 
    336 	if memcmp(v, sig, 4) {
    337 		return 0;
    338 	}
    339 
    340 	len = acpi_len(p);
    341 	if len < 36 {
    342 		return 0;
    343 	}
    344 
    345 	if bytesum(v, len) as int != 0 {
    346 		return 0;
    347 	}
    348 
    349 	return len;
    350 }
    351 
    352 func kputh(x: int) {
    353 	_kputh(x, 64);
    354 }
    355 
    356 func kputh8(x: int) {
    357 	_kputh(x, 8);
    358 }
    359 
    360 func kputh16(x: int) {
    361 	_kputh(x, 16);
    362 }
    363 
    364 func kputh32(x: int) {
    365 	_kputh(x, 32);
    366 }
    367 
    368 func _kputh(x: int, d: int) {
    369 	loop {
    370 		if d == 0 {
    371 			break;
    372 		}
    373 		d = d - 4;
    374 		kputc("0123456789abcdef"[(x >> d) & 15] as int);
    375 	}
    376 }
    377 
    378 func kputd(x: int) {
    379 	var a: int;
    380 
    381 	if x < 0 {
    382 		kputc('-');
    383 		a = -(x % 10);
    384 		x = x / -10;
    385 	} else {
    386 		a = x % 10;
    387 		x = x / 10;
    388 	}
    389 
    390 	if x != 0 {
    391 		kputd(x);
    392 	}
    393 
    394 	kputc('0' + a);
    395 }
    396 
    397 func find_rsdt(): int {
    398 	var p: int;
    399 	var v: *byte;
    400 	var len: int;
    401 
    402 	// Find the RDSP
    403 	p = 0xe0000;
    404 	loop {
    405 		v = ptov(p);
    406 
    407 		if p + 20 >= 0xfffff {
    408 			return 0;
    409 		}
    410 
    411 		if !memcmp(v, "RSD PTR ", 8) {
    412 			if !bytesum(v, 20) {
    413 				break;
    414 			}
    415 		}
    416 
    417 		p = p + 16;
    418 	}
    419 
    420 	p = _r32(&v[16]);
    421 	if valid_table(p, "RSDT") == 0 {
    422 		return 0;
    423 	}
    424 
    425 	return p;
    426 }
    427 
    428 func find_acpi(rsdt: int, sig: *byte): int {
    429 	var i: int;
    430 	var len: int;
    431 	var p: int;
    432 
    433 	if rsdt == 0 {
    434 		return 0;
    435 	}
    436 
    437 	i = 36;
    438 	len = acpi_len(rsdt);
    439 
    440 	loop {
    441 		if i >= len {
    442 			return 0;
    443 		}
    444 
    445 		p = _r32(ptov(rsdt + i));
    446 
    447 		if valid_table(p, sig) != 0 {
    448 			return p;
    449 		}
    450 
    451 		i = i + 4;
    452 	}
    453 }
    454 
    455 func map_pci(pa: int): *byte {
    456 	var global: *global;
    457 	var va: int;
    458 	var pt4p: int;
    459 	var pt4: *int;
    460 	var pt3: *int;
    461 	var v2: int;
    462 	var flags: int;
    463 	global = g();
    464 	global.mmio = global.mmio - (1 << 31);
    465 	va = global.mmio;
    466 	pt4p = global.kpt;
    467 	pt4 = ptov(pt4p) as *int;
    468 	v2 = ((va as int) >> 30) & 511;
    469 	pt3 = ptov(pt4[511] & -4096) as *int;
    470 	flags = 0x93;
    471 	pt3[v2] = (pa & -(1 << 30)) | flags;
    472 	pt3[v2 + 1] = ((pa + (1 << 30)) & -(1 << 30)) | flags;
    473 	invlpt();
    474 	return (va + (pa & ((1 << 30) - 1))) as *byte;
    475 }
    476 
    477 struct pcidev {
    478 	addr: *byte;
    479 	type: int;
    480 	bus: int;
    481 	vid: int;
    482 	did: int;
    483 	cls: int;
    484 	subcls: int;
    485 	bar0: int;
    486 	bar1: int;
    487 	bar2: int;
    488 	bar3: int;
    489 	bar4: int;
    490 	bar5: int;
    491 	trap: *byte;
    492 	msi: *byte;
    493 }
    494 
    495 func scan_pci(base: *byte, visit: func(dev: *pcidev)) {
    496 	var i: int;
    497 	var cap: int;
    498 	var capid: int;
    499 	var dev: pcidev;
    500 	i = 0;
    501 	loop {
    502 		if i == 256*64 {
    503 			break;
    504 		}
    505 
    506 		dev.addr = &base[i * 4096];
    507 		dev.bus = i;
    508 
    509 		dev.type = base[i * 4096 + 14] as int;
    510 
    511 		dev.vid = (base[i * 4096 + 0] as int)
    512 			+ (base[i * 4096 + 1] as int << 8);
    513 		dev.did = (base[i * 4096 + 2] as int)
    514 			+ (base[i * 4096 + 3] as int << 8);
    515 		dev.cls = base[i * 4096 + 11] as int;
    516 		dev.subcls = base[i * 4096 + 10] as int;
    517 		dev.bar0 = _r32(&base[i * 4096 + 16 + 4 * 0]);
    518 		dev.bar1 = _r32(&base[i * 4096 + 16 + 4 * 1]);
    519 		dev.bar2 = _r32(&base[i * 4096 + 16 + 4 * 2]);
    520 		dev.bar3 = _r32(&base[i * 4096 + 16 + 4 * 3]);
    521 		dev.bar4 = _r32(&base[i * 4096 + 16 + 4 * 4]);
    522 		dev.bar5 = _r32(&base[i * 4096 + 16 + 4 * 5]);
    523 
    524 		dev.trap = &base[i * 4096 + 60];
    525 
    526 		if dev.vid == 0xffff {
    527 			i = i + 1;
    528 			continue;
    529 		}
    530 
    531 		dev.msi = nil;
    532 
    533 		if dev.type == 0 {
    534 			cap = base[i * 4096 + 0x34] as int;
    535 			loop {
    536 				if cap == 0 || cap > 4094 {
    537 					break;
    538 				}
    539 
    540 				capid = base[i * 4096 + cap] as int;
    541 
    542 				if capid == 5 {
    543 					dev.msi = &base[i * 4096 + cap];
    544 					break;
    545 				}
    546 
    547 				cap = base[i * 4096 + cap + 1] as int;
    548 			}
    549 		}
    550 
    551 		visit(&dev);
    552 
    553 		i = i + 1;
    554 	}
    555 }
    556 
    557 func show_pcidev(dev: *pcidev) {
    558 	kputh16(dev.bus);
    559 	kputc(':');
    560 	kputc(' ');
    561 	kputh16(dev.vid);
    562 	kputc(':');
    563 	kputh16(dev.did);
    564 	kputc(' ');
    565 	kputh8(dev.cls);
    566 	kputc(':');
    567 	kputh8(dev.subcls);
    568 	kputc(' ');
    569 	kputh32(dev.bar0);
    570 	kputc(' ');
    571 	kputh32(dev.bar1);
    572 	kputc(' ');
    573 	kputh32(dev.bar2);
    574 	kputc(' ');
    575 	kputh32(dev.bar3);
    576 	kputc(' ');
    577 	kputh32(dev.bar4);
    578 	kputc(' ');
    579 	kputh32(dev.bar5);
    580 	kputc('\n');
    581 }
    582 
    583 func onesum(h: *byte, n: int, s: int): int {
    584 	var i: int;
    585 	i = 0;
    586 	s = (s & 0xffff) + (s >> 16);
    587 	s = (s & 0xffff) + (s >> 16);
    588 	s = (s & 0xffff) + (s >> 16);
    589 	loop {
    590 		if i >= n {
    591 			break;
    592 		}
    593 		if i + 1 == n {
    594 			s = s + (h[i] as int << 8);
    595 			s = (s & 0xffff) + ((s >> 16) & 1);
    596 			break;
    597 		}
    598 		s = s + (h[i] as int << 8) + (h[i + 1] as int);
    599 		s = (s & 0xffff) + ((s >> 16) & 1);
    600 		i = i + 2;
    601 	}
    602 	return s;
    603 }
    604 
    605 struct vga {
    606 	base: *byte;
    607 	fb: *byte;
    608 	cx: int;
    609 	cy: int;
    610 	x: int;
    611 	y: int;
    612 }
    613 
    614 func vinit(v: *vga, base: *byte, fb: *byte) {
    615 	v.base = base;
    616 	v.fb = fb;
    617 	v.cx = 80;
    618 	v.cy = 25;
    619 	v.x = 0;
    620 	v.y = 0;
    621 }
    622 
    623 func vcursor(v: *vga) {
    624 	var i: int;
    625 	i = v.y * v.cx + v.x;
    626 	outb(0x3d4, 0x0f);
    627 	outb(0x3d5, i);
    628 	outb(0x3d4, 0x0e);
    629 	outb(0x3d5, i >> 8);
    630 }
    631 
    632 func vblit(v: *vga) {
    633 	var i: int;
    634 	var d: *int;
    635 	var s: *int;
    636 
    637 	d = v.base as *int;
    638 	s = v.fb as *int;
    639 
    640 	i = 0;
    641 	loop {
    642 		if i == 512 {
    643 			break;
    644 		}
    645 
    646 		d[i] = s[i];
    647 
    648 		i = i + 1;
    649 	}
    650 }
    651 
    652 func vclear(v: *vga) {
    653 	var i: int;
    654 	v.x = 0;
    655 	v.y = 0;
    656 	vcursor(v);
    657 	i = 0;
    658 	loop {
    659 		if i == v.cx * v.cy {
    660 			return;
    661 		}
    662 		v.fb[2 * i] = 0 as byte;
    663 		v.fb[2 * i + 1] = 0x0f as byte;
    664 		i = i + 1;
    665 	}
    666 	vblit(v);
    667 }
    668 
    669 func vshift(v: *vga) {
    670 	var i: int;
    671 	memcpy(v.fb, &v.fb[v.cx * 2], (v.cy - 1) * v.cx * 2);
    672 	i = (v.cy - 1) * v.cx;
    673 	loop {
    674 		if i == v.cx * v.cy {
    675 			break;
    676 		}
    677 		v.fb[2 * i] = 0 as byte;
    678 		v.fb[2 * i + 1] = 0x0f as byte;
    679 		i = i + 1;
    680 	}
    681 	if v.y > 0 {
    682 		v.y = v.y - 1;
    683 	}
    684 	vblit(v);
    685 }
    686 
    687 func vputc(v: *vga, c: int) {
    688 	if c == '\r' {
    689 		v.x = 0;
    690 		vblit(v);
    691 	} else if c == '\n' {
    692 		v.x = 0;
    693 		v.y = v.y + 1;
    694 		if v.y == v.cy {
    695 			vshift(v);
    696 		} else {
    697 			vblit(v);
    698 		}
    699 	} else {
    700 		v.fb[(v.y * v.cx + v.x) * 2] = c as byte;
    701 		v.fb[(v.y * v.cx + v.x) * 2 + 1] = 0x0f as byte;
    702 		v.x = v.x + 1;
    703 		if v.x == v.cx {
    704 			v.x = 0;
    705 			v.y = v.y + 1;
    706 			if v.y == v.cy {
    707 				vshift(v);
    708 			} else {
    709 				vblit(v);
    710 			}
    711 		}
    712 	}
    713 	vcursor(v);
    714 }
    715 
    716 func kputc(c: int) {
    717 	var global: *global;
    718 	global = g();
    719 	vputc(&global.vga, c);
    720 }
    721 
    722 func kputs(s: *byte) {
    723 	var i: int;
    724 	var global: *global;
    725 	global = g();
    726 	i = 0;
    727 	loop {
    728 		if !s[i] {
    729 			break;
    730 		}
    731 		vputc(&global.vga, s[i] as int);
    732 		i = i + 1;
    733 	}
    734 }
    735 
    736 struct arp_entry {
    737 	mac: int;
    738 	ip: int;
    739 	last_seen: int;
    740 	state: int;
    741 }
    742 
    743 struct tcp_state {
    744 	state: int;
    745 
    746 	event_func: func(tcb: *tcp_state);
    747 
    748 	// Network tuple
    749 	peer_ip: int;
    750 	peer_port: int;
    751 	sock_ip: int;
    752 	sock_port: int;
    753 
    754 	deadline: int;
    755 	rto: int;
    756 
    757 	recv_nxt: int;
    758 	recv_len: int;
    759 	recv_buf: *byte;
    760 
    761 	send_fin: int;
    762 	send_ack: int;
    763 	send_una: int;
    764 	send_nxt: int;
    765 	send_wnd: int;
    766 	send_len: int;
    767 	send_buf: *byte;
    768 
    769 	fin_seq: int;
    770 
    771 	task: *task;
    772 }
    773 
    774 struct task {
    775 	next: *task;
    776 	prev: *task;
    777 	cwd: *vfile;
    778 	name: *byte;
    779 	files: **vfile;
    780 	stack: *byte;
    781 	dead: int;
    782 	f: (func(t: *task));
    783 	a: *void;
    784 	regs: regs;
    785 	pt: int;
    786 }
    787 
    788 struct global {
    789 	ptr: *global;
    790 	ms: int;
    791 	vga: vga;
    792 	fr: *free_range;
    793 	fp: *free_page;
    794 	kpt: int;
    795 	lapicp: int;
    796 	lapic: *byte;
    797 	mmio: int;
    798 	realtek_port: *realtek_port;
    799 	ahci_port: *ahci_port;
    800 	boot_time: int;
    801 	ip: int;
    802 	ip_gw: int;
    803 	ip_mask: int;
    804 	arp: *arp_entry;
    805 	arp_count: int;
    806 	tcp: **tcp_state;
    807 	tcp_count: int;
    808 	curtask: *task;
    809 	dead: *task;
    810 	_save: int;
    811 	root: *vfile;
    812 	next_ino: int;
    813 }
    814 
    815 struct free_page {
    816 	next: *free_page;
    817 	pa: int;
    818 }
    819 
    820 struct free_range {
    821 	next: *free_range;
    822 	start: int;
    823 	end: int;
    824 }
    825 
    826 func g(): *global {
    827 	return _rgs(0) as **global[0];
    828 }
    829 
    830 func rand(): int {
    831 	return _rdrand();
    832 }
    833 
    834 func memset(dest: *byte, c: int, size: int) {
    835 	var i: int;
    836 
    837 	if size < 0 {
    838 		return;
    839 	}
    840 
    841 	i = 0;
    842 	loop {
    843 		if i == size {
    844 			break;
    845 		}
    846 		dest[i] = c as byte;
    847 		i = i + 1;
    848 	}
    849 }
    850 
    851 func memcpy(dest: *byte, src: *byte, size: int) {
    852 	var i: int;
    853 
    854 	if size < 0 {
    855 		return;
    856 	}
    857 
    858 	if src > dest {
    859 		i = 0;
    860 		loop {
    861 			if i == size {
    862 				break;
    863 			}
    864 			dest[i] = src[i];
    865 			i = i + 1;
    866 		}
    867 	} else if src < dest {
    868 		i = size;
    869 		loop {
    870 			if i == 0 {
    871 				break;
    872 			}
    873 			i = i - 1;
    874 			dest[i] = src[i];
    875 		}
    876 	}
    877 }
    878 
    879 func memswap(a: *byte, b: *byte, size: int) {
    880 	var i: int;
    881 	var t: byte;
    882 
    883 	if size < 0 {
    884 		return;
    885 	}
    886 
    887 	i = 0;
    888 	loop {
    889 		if i == size {
    890 			break;
    891 		}
    892 		t = a[i];
    893 		a[i] = b[i];
    894 		b[i] = t;
    895 		i = i + 1;
    896 	}
    897 }
    898 
    899 func insert_sort(arr: *void, nitems: int, size: int, cmp: (func(a: *void, b: *void): int)) {
    900 	var i: int;
    901 	var j: int;
    902 	var a: *void;
    903 	var b: *void;
    904 
    905 	if nitems <= 1 || size <= 0 {
    906 		return;
    907 	}
    908 
    909 	i = 1;
    910 	loop {
    911 		if i == nitems {
    912 			break;
    913 		}
    914 
    915 		j = i - 1;
    916 
    917 		b = (&arr as *byte[size * i]) as *void;
    918 
    919 		loop {
    920 			a = (&arr as *byte[size * j]) as *void;
    921 
    922 			if cmp(a, b) <= 0 {
    923 				break;
    924 			}
    925 
    926 			memswap(a as *byte, b as *byte, size);
    927 
    928 			if j == 0 {
    929 				break;
    930 			}
    931 
    932 			j = j - 1;
    933 		}
    934 
    935 		i = i + 1;
    936 	}
    937 }
    938 
    939 func mmap_cmp(a: *void, b: *void): int {
    940 	var a_addr: int;
    941 	var b_addr: int;
    942 	a_addr = a as *int[0];
    943 	b_addr = b as *int[0];
    944 	if a_addr < b_addr {
    945 		return -1;
    946 	} else if a_addr > b_addr {
    947 		return 1;
    948 	}
    949 	return 0;
    950 }
    951 
    952 func free(p: *byte) {
    953 	var global: *global;
    954 	var fp: *free_page;
    955 	var flags: int;
    956 
    957 	global = g();
    958 
    959 	if !p {
    960 		return;
    961 	}
    962 
    963 	if p as int & 4095 != 0 {
    964 		kdie("BAD FREE");
    965 	}
    966 
    967 	fp = p as *free_page;
    968 	fp.pa = vtop(p);
    969 
    970 	flags = rdflags();
    971 	cli();
    972 	fp.next = global.fp;
    973 	global.fp = fp;
    974 	wrflags(flags);
    975 }
    976 
    977 func alloc_page(): int {
    978 	var global: *global;
    979 	var fr: *free_range;
    980 	var fp: *free_page;
    981 	var flags: int;
    982 	var ret: int;
    983 	global = g();
    984 
    985 	flags = rdflags();
    986 	cli();
    987 
    988 	fp = global.fp;
    989 	if fp {
    990 		global.fp = fp.next;
    991 		wrflags(flags);
    992 		return fp.pa;
    993 	}
    994 	fr = global.fr;
    995 	loop {
    996 		if !fr {
    997 			break;
    998 		}
    999 
   1000 		if fr.start < fr.end {
   1001 			ret = fr.start;
   1002 			fr.start = fr.start + 4096;
   1003 			wrflags(flags);
   1004 			return ret;
   1005 		}
   1006 
   1007 		fr = fr.next;
   1008 	}
   1009 
   1010 	kdie("OOM");
   1011 	return 0;
   1012 }
   1013 
   1014 func direct_map(brk: *int) {
   1015 	var pt4p: int;
   1016 	var pt4: *int;
   1017 	var pt3p: int;
   1018 	var pt3: *int;
   1019 	var va: int;
   1020 	var pa: int;
   1021 	var page_size: int;
   1022 	var map_size: int;
   1023 	var i: int;
   1024 	var n: int;
   1025 	var global: *global;
   1026 
   1027 	global = g();
   1028 
   1029 	map_size = 1 << 46;
   1030 	page_size = 1 << 30;
   1031 
   1032 	va = -1 << 47;
   1033 	pa = 0;
   1034 
   1035 	pt4p = global.kpt;
   1036 	pt4 = ptov(pt4p) as *int;
   1037 
   1038 	brk[0] = (brk[0] + 4095) & -4096;
   1039 
   1040 	loop {
   1041 		if pa == map_size {
   1042 			break;
   1043 		}
   1044 
   1045 		n = 512;
   1046 
   1047 		pt3 = brk[0] as *int;
   1048 		brk[0] = brk[0] + 4096;
   1049 		pt3p = (pt3 as int) & ((1 << 31) - 1);
   1050 
   1051 		i = (va >> 39) & 511;
   1052 		pt4[i] = pt3p | 0x003;
   1053 
   1054 		loop {
   1055 			if pa == map_size || n == 0 {
   1056 				break;
   1057 			}
   1058 
   1059 			i = (va >> 30) & 511;
   1060 			pt3[i] = pa | 0x083;
   1061 
   1062 			va = va + page_size;
   1063 			pa = pa + page_size;
   1064 			n = n - 1;
   1065 		}
   1066 	}
   1067 
   1068 	invlpt();
   1069 }
   1070 
   1071 func invlpt() {
   1072 	var global: *global;
   1073 	var t: *task;
   1074 	var tpt: *int;
   1075 	var kpt: *int;
   1076 	var i: int;
   1077 	global = g();
   1078 	t = global.curtask;
   1079 	if t.pt == global.kpt {
   1080 		wrcr3(global.kpt);
   1081 		return;
   1082 	}
   1083 	tpt = ptov(t.pt) as *int;
   1084 	kpt = ptov(global.kpt) as *int;
   1085 	i = 256;
   1086 	loop {
   1087 		if i == 512 {
   1088 			break;
   1089 		}
   1090 		tpt[i] = kpt[i];
   1091 		i = i + 1;
   1092 	}
   1093 	wrcr3(t.pt);
   1094 }
   1095 
   1096 func setup_ring(ring: int, own: int) {
   1097 	var v: *byte;
   1098 	var i: int;
   1099 	var p: int;
   1100 
   1101 	v = ptov(ring);
   1102 	i = 0;
   1103 
   1104 	loop {
   1105 		if i == 16 {
   1106 			break;
   1107 		}
   1108 
   1109 		p = alloc_page();
   1110 
   1111 		_w32(&v[i * 16], (own << 31) | ((i == 15) << 30) | 4096);
   1112 		_w32(&v[i * 16 + 4], 0);
   1113 		_w32(&v[i * 16 + 8], p);
   1114 		_w32(&v[i * 16 + 12], p >> 32);
   1115 
   1116 		i = i + 1;
   1117 	}
   1118 }
   1119 
   1120 struct realtek_desc {
   1121 	flags: int;
   1122 	framep: int;
   1123 }
   1124 
   1125 struct realtek_port {
   1126 	next: *realtek_port;
   1127 	io: int;
   1128 	mac: int;
   1129 	tx: realtek_ring;
   1130 	rx: realtek_ring;
   1131 }
   1132 
   1133 struct realtek_ring {
   1134 	ringp: int;
   1135 	ring: *realtek_desc;
   1136 	count: int;
   1137 	index: int;
   1138 }
   1139 
   1140 func alloc(): *byte {
   1141 	return ptov(alloc_page());
   1142 }
   1143 
   1144 func realtek_mkring(ring: *realtek_ring, rx: int) {
   1145 	var i: int;
   1146 	ring.count = 4096 >> 4;
   1147 	ring.index = 0;
   1148 	ring.ringp = alloc_page();
   1149 	ring.ring = ptov(ring.ringp) as *realtek_desc;
   1150 	i = 0;
   1151 	loop {
   1152 		if i == ring.count {
   1153 			break;
   1154 		}
   1155 		ring.ring[i].framep = alloc_page();
   1156 		ring.ring[i].flags = (rx << 31) + (((i + 1) == ring.count) << 30) + 4095;
   1157 		i = i + 1;
   1158 	}
   1159 }
   1160 
   1161 func init_realtek(dev: *pcidev) {
   1162 	var global: *global;
   1163 	var realtek_port: *realtek_port;
   1164 	var io: int;
   1165 
   1166 	global = g();
   1167 
   1168 	if dev.vid != 0x10ec || dev.did != 0x8168 {
   1169 		return;
   1170 	}
   1171 
   1172 	if dev.bar0 & 1 != 1 {
   1173 		return;
   1174 	}
   1175 
   1176 	io = dev.bar0 & -2;
   1177 
   1178 	// Enable dma
   1179 	_w16(&dev.addr[4], 7);
   1180 
   1181 	// Reset
   1182 	outb(io + 0x37, 0x10);
   1183 	loop {
   1184 		if (inb(io + 0x37) & 0x10) == 0 {
   1185 			break;
   1186 		}
   1187 	}
   1188 
   1189 	// Disable interrupts
   1190 	outw(io + 0x3c, 0x0000);
   1191 
   1192 	// Setup MSI
   1193 	_w16(&dev.msi[2], 0x0081);
   1194 	_w32(&dev.msi[4], global.lapicp);
   1195 	_w32(&dev.msi[8], global.lapicp >> 32);
   1196 	_w16(&dev.msi[12], 33);
   1197 
   1198 	// Config write enable
   1199 	outb(io + 0x50, 0xc0);
   1200 
   1201 	// rx config
   1202 	outd(io + 0x44, 0x0000e70f);
   1203 
   1204 	// tx config
   1205 	outb(io + 0x37, 0x0c);
   1206 	outd(io + 0x40, 0x03000700);
   1207 
   1208 	// rx packet size
   1209 	outd(io + 0xda, 0x00000800);
   1210 
   1211 	// tx packet size
   1212 	outd(io + 0xec, 0x00000010);
   1213 
   1214 	var mac: int;
   1215 	realtek_port = alloc() as *realtek_port;
   1216 	realtek_port.io = io;
   1217 	mac = ind(io); mac = mac + (ind(io + 4) << 32);
   1218 	realtek_port.mac = ((mac >> 40) & 0xff)
   1219 		+ (((mac >> 32) & 0xff) << 8)
   1220 		+ (((mac >> 24) & 0xff) << 16)
   1221 		+ (((mac >> 16) & 0xff) << 24)
   1222 		+ (((mac >> 8) & 0xff) << 32)
   1223 		+ ((mac & 0xff) << 40);
   1224 	realtek_mkring(&realtek_port.tx, 0);
   1225 	realtek_mkring(&realtek_port.rx, 1);
   1226 
   1227 	// tx ring
   1228 	outd(io + 0x20, realtek_port.tx.ringp);
   1229 	outd(io + 0x24, realtek_port.tx.ringp >> 32);
   1230 
   1231 	// tx max size
   1232 	outb(io + 0xec, 16);
   1233 
   1234 	// rx ring
   1235 	outd(io + 0xe4, realtek_port.rx.ringp);
   1236 	outd(io + 0xe8, realtek_port.rx.ringp >> 32);
   1237 
   1238 	// Enable rx/tx
   1239 	outd(io + 0x37, 0x0c);
   1240 
   1241 	// Enable interrupts
   1242 	outw(io + 0x3c, 0x00ff);
   1243 	outw(io + 0x3e, 0xffff);
   1244 
   1245 	// Config write disable
   1246 	outb(io + 0x50, 0x00);
   1247 
   1248 	// TX Doorbell
   1249 	//fill_packet(txringp);
   1250 	//outb(io + 0x38, 0x40);
   1251 
   1252 	realtek_port.next = global.realtek_port;
   1253 	global.realtek_port = realtek_port;
   1254 }
   1255 
   1256 func kputmac(a: int) {
   1257 	kputh8((a >> 40) & 0xff);
   1258 	kputc(':');
   1259 	kputh8((a >> 32) & 0xff);
   1260 	kputc(':');
   1261 	kputh8((a >> 24) & 0xff);
   1262 	kputc(':');
   1263 	kputh8((a >> 16) & 0xff);
   1264 	kputc(':');
   1265 	kputh8((a >> 8) & 0xff);
   1266 	kputc(':');
   1267 	kputh8(a & 0xff);
   1268 }
   1269 
   1270 func kputip(a: int) {
   1271 	kputd((a >> 24) & 0xff);
   1272 	kputc('.');
   1273 	kputd((a >> 16) & 0xff);
   1274 	kputc('.');
   1275 	kputd((a >> 8) & 0xff);
   1276 	kputc('.');
   1277 	kputd(a & 0xff);
   1278 }
   1279 
   1280 enum {
   1281 	ET_IP = 0x0800,
   1282 	ET_ARP = 0x0806,
   1283 	ARP_ETHER = 1,
   1284 	IP_ICMP = 1,
   1285 	IP_TCP = 6,
   1286 	IP_UDP = 17,
   1287 	ICMP_PONG = 0,
   1288 	ICMP_PING = 8,
   1289 }
   1290 
   1291 struct rxinfo {
   1292 	port: *realtek_port;
   1293 
   1294 	ether: *byte;
   1295 	ether_len: int;
   1296 	ether_src: int;
   1297 	ether_dest: int;
   1298 	ether_type: int;
   1299 
   1300 	arp: *byte;
   1301 	arp_len: int;
   1302 	arp_op: int;
   1303 	arp_ether_src: int;
   1304 	arp_ip_src: int;
   1305 	arp_ether_dest: int;
   1306 	arp_ip_dest: int;
   1307 
   1308 	ip: *byte;
   1309 	ip_len: int;
   1310 	ip_src: int;
   1311 	ip_dest: int;
   1312 	ip_proto: int;
   1313 	ip_psum: int;
   1314 
   1315 	icmp: *byte;
   1316 	icmp_len: int;
   1317 	icmp_type: int;
   1318 	icmp_code: int;
   1319 	icmp_id: int;
   1320 	icmp_seq: int;
   1321 
   1322 	icmp_seg: *byte;
   1323 	icmp_seg_len: int;
   1324 
   1325 	udp: *byte;
   1326 	udp_len: int;
   1327 	udp_src: int;
   1328 	udp_dest: int;
   1329 
   1330 	udp_seg: *byte;
   1331 	udp_seg_len: int;
   1332 
   1333 	tcp: *byte;
   1334 	tcp_len: int;
   1335 	tcp_src: int;
   1336 	tcp_dest: int;
   1337 	tcp_seq: int;
   1338 	tcp_ack: int;
   1339 	tcp_flags: int;
   1340 	tcp_win: int;
   1341 	tcp_opt: *byte;
   1342 	tcp_opt_len: int;
   1343 
   1344 	tcp_seg: *byte;
   1345 	tcp_seg_len: int;
   1346 }
   1347 
   1348 func memo_arp(ether: int, ip: int, auth: int) {
   1349 	var global: *global;
   1350 	var mask: int;
   1351 	global = g();
   1352 
   1353 	// Filter multicast ether sources
   1354 	if ether & (1 << 40) {
   1355 		return;
   1356 	}
   1357 
   1358 	// Filter all zeros mac
   1359 	if ether == 0 {
   1360 		return;
   1361 	}
   1362 
   1363 	// Filter all zeros ip or all ones ip
   1364 	if ip == 0 || (ip + 1) >> 32 {
   1365 		return;
   1366 	}
   1367 
   1368 	// Filter different networks
   1369 	mask = -1 << (32 - global.ip_mask);
   1370 	if (global.ip & mask) != (ip & mask) {
   1371 		return;
   1372 	}
   1373 
   1374 	var i: int;
   1375 	var j: int;
   1376 	i = 0;
   1377 	j = 0;
   1378 
   1379 	// Check if ip is already in the table
   1380 	loop {
   1381 		if i == global.arp_count {
   1382 			break;
   1383 		}
   1384 
   1385 		// Update the entry for this ip if we've already seen it
   1386 		if global.arp[i].state != ARP_EMPTY && global.arp[i].ip == ip {
   1387 			global.arp[i].mac = ether;
   1388 			global.arp[i].last_seen = global.ms;
   1389 			global.arp[i].state = ARP_LIVE;
   1390 			return;
   1391 		}
   1392 
   1393 		i = i + 1;
   1394 	}
   1395 
   1396 	if !auth {
   1397 		return;
   1398 	}
   1399 
   1400 	// Find an empty slot
   1401 	i = 0;
   1402 	loop {
   1403 		if i == global.arp_count {
   1404 			i = j;
   1405 			break;
   1406 		}
   1407 
   1408 		// Use the first free entry
   1409 		if global.arp[i].state == ARP_EMPTY {
   1410 			break;
   1411 		}
   1412 
   1413 		// Or evict the oldest entry if none are free
   1414 		if global.arp[i].last_seen < global.arp[j].last_seen {
   1415 			j = i;
   1416 		}
   1417 
   1418 		i = i + 1;
   1419 	}
   1420 
   1421 	// Add it to the memo table
   1422 	global.arp[i].mac = ether;
   1423 	global.arp[i].ip = ip;
   1424 	global.arp[i].last_seen = global.ms;
   1425 	global.arp[i].state = ARP_LIVE;
   1426 }
   1427 
   1428 enum {
   1429 	// Empty entry in the arp table
   1430 	ARP_EMPTY = 0,
   1431 	// Valid entry in the arp table
   1432 	ARP_LIVE = 1,
   1433 	// Time to consider an entry stale
   1434 	ARP_THRESH = 15000,
   1435 }
   1436 
   1437 struct txinfo {
   1438 	buf: *byte;
   1439 	len: int;
   1440 
   1441 	port: *realtek_port;
   1442 
   1443 	ether_type: int;
   1444 	ether_src: int;
   1445 	ether_dest: int;
   1446 
   1447 	ip_proto: int;
   1448 	ip_src: int;
   1449 	ip_dest: int;
   1450 
   1451 	icmp_type: int;
   1452 	icmp_code: int;
   1453 	icmp_id: int;
   1454 	icmp_seq: int;
   1455 
   1456 	udp_src: int;
   1457 	udp_dest: int;
   1458 
   1459 	tcp_src: int;
   1460 	tcp_dest: int;
   1461 	tcp_seq: int;
   1462 	tcp_ack: int;
   1463 	tcp_flags: int;
   1464 	tcp_win: int;
   1465 	tcp_opt: *byte;
   1466 	tcp_opt_len: int;
   1467 }
   1468 
   1469 func alloc_tx(): *txinfo {
   1470 	var pkt: *txinfo;
   1471 	pkt = alloc() as *txinfo;
   1472 	bzero(pkt as *byte, 4096);
   1473 	pkt.buf = &(pkt as *byte)[1024];
   1474 	return pkt;
   1475 }
   1476 
   1477 func free_tx(pkt: *txinfo) {
   1478 	free(pkt as *byte);
   1479 }
   1480 
   1481 func send_realtek(pkt: *txinfo) {
   1482 	var port: *realtek_port;
   1483 	var i: int;
   1484 	var flags: int;
   1485 
   1486 	flags = rdflags();
   1487 	cli();
   1488 
   1489 	port = pkt.port;
   1490 	if !port {
   1491 		wrflags(flags);
   1492 		return;
   1493 	}
   1494 
   1495 	if port.tx.index >= port.tx.count {
   1496 		port.tx.index = 0;
   1497 	}
   1498 	i = port.tx.index;
   1499 	port.tx.index = i +1;
   1500 
   1501 	if port.tx.ring[i].flags & (1 << 31) != 0 {
   1502 		wrflags(flags);
   1503 		return;
   1504 	}
   1505 
   1506 	memcpy(ptov(port.tx.ring[i].framep), pkt.buf, pkt.len);
   1507 	port.tx.ring[i].flags = (port.tx.ring[i].flags & (1 << 30)) + (0xb << 28) + pkt.len;
   1508 	outd(port.io + 0x38, 0x40);
   1509 	wrflags(flags);
   1510 }
   1511 
   1512 func send_ether(pkt: *txinfo) {
   1513 	pkt.buf = &pkt.buf[-14];
   1514 	pkt.len = pkt.len + 14;
   1515 
   1516 	pkt.buf[0] = (pkt.ether_dest >> 40) as byte;
   1517 	pkt.buf[1] = (pkt.ether_dest >> 32) as byte;
   1518 	pkt.buf[2] = (pkt.ether_dest >> 24) as byte;
   1519 	pkt.buf[3] = (pkt.ether_dest >> 16) as byte;
   1520 	pkt.buf[4] = (pkt.ether_dest >> 8) as byte;
   1521 	pkt.buf[5] = pkt.ether_dest as byte;
   1522 
   1523 	pkt.buf[6] = (pkt.ether_src >> 40) as byte;
   1524 	pkt.buf[7] = (pkt.ether_src >> 32) as byte;
   1525 	pkt.buf[8] = (pkt.ether_src >> 24) as byte;
   1526 	pkt.buf[9] = (pkt.ether_src >> 16) as byte;
   1527 	pkt.buf[10] = (pkt.ether_src >> 8) as byte;
   1528 	pkt.buf[11] = pkt.ether_src as byte;
   1529 
   1530 	pkt.buf[12] = (pkt.ether_type >> 8) as byte;
   1531 	pkt.buf[13] = pkt.ether_type as byte;
   1532 
   1533 	send_realtek(pkt);
   1534 }
   1535 
   1536 func send_arp2(port: *realtek_port, tha: int, tpa: int) {
   1537 	var pkt: *txinfo;
   1538 	var global: *global;
   1539 	var sha: int;
   1540 	var spa: int;
   1541 	global = g();
   1542 
   1543 	if tha & (1 << 40) {
   1544 		return;
   1545 	}
   1546 
   1547 	if tha == 0 {
   1548 		return;
   1549 	}
   1550 
   1551 	sha = port.mac;
   1552 	spa = global.ip;
   1553 
   1554 	pkt = alloc_tx();
   1555 	pkt.port = port;
   1556 
   1557 	// htype
   1558 	pkt.buf[0] = 0 as byte;
   1559 	pkt.buf[1] = 1 as byte;
   1560 
   1561 	// ptype
   1562 	pkt.buf[2] = (ET_IP >> 8) as byte;
   1563 	pkt.buf[3] = (ET_IP) as byte;
   1564 
   1565 	// hlen
   1566 	pkt.buf[4] = 6 as byte;
   1567 
   1568 	// plen
   1569 	pkt.buf[5] = 4 as byte;
   1570 
   1571 	// oper
   1572 	pkt.buf[6] = 0 as byte;
   1573 	pkt.buf[7] = 2 as byte;
   1574 
   1575 	// sha
   1576 	pkt.buf[8] = (sha >> 40) as byte;
   1577 	pkt.buf[9] = (sha >> 32) as byte;
   1578 	pkt.buf[10] = (sha >> 24) as byte;
   1579 	pkt.buf[11] = (sha >> 16) as byte;
   1580 	pkt.buf[12] = (sha >> 8) as byte;
   1581 	pkt.buf[13] = sha as byte;
   1582 
   1583 	// spa
   1584 	pkt.buf[14] = (spa >> 24) as byte;
   1585 	pkt.buf[15] = (spa >> 16) as byte;
   1586 	pkt.buf[16] = (spa >> 8) as byte;
   1587 	pkt.buf[17] = spa as byte;
   1588 
   1589 	// tha
   1590 	pkt.buf[18] = (tha >> 40) as byte;
   1591 	pkt.buf[19] = (tha >> 32) as byte;
   1592 	pkt.buf[20] = (tha >> 24) as byte;
   1593 	pkt.buf[21] = (tha >> 16) as byte;
   1594 	pkt.buf[22] = (tha >> 8) as byte;
   1595 	pkt.buf[23] = tha as byte;
   1596 
   1597 	// tpa
   1598 	pkt.buf[24] = (tpa >> 24) as byte;
   1599 	pkt.buf[25] = (tpa >> 16) as byte;
   1600 	pkt.buf[26] = (tpa >> 8) as byte;
   1601 	pkt.buf[27] = tpa as byte;
   1602 
   1603 	pkt.len = 28;
   1604 
   1605 	pkt.ether_type = ET_ARP;
   1606 	pkt.ether_src = sha;
   1607 	pkt.ether_dest = tha;
   1608 
   1609 	send_ether(pkt);
   1610 
   1611 	free_tx(pkt);
   1612 }
   1613 
   1614 func handle_arp(pkt: *rxinfo) {
   1615 	var global: *global;
   1616 	global = g();
   1617 
   1618 	// Add arp_ether_src arp_ip_src to the arp table
   1619 	memo_arp(pkt.arp_ether_src, pkt.arp_ip_src, 1);
   1620 
   1621 	if pkt.arp_ip_dest != global.ip {
   1622 		return;
   1623 	}
   1624 
   1625 	if pkt.arp_op == 1 {
   1626 		// Send ARP response
   1627 		send_arp2(pkt.port, pkt.arp_ether_src, pkt.arp_ip_src);
   1628 	}
   1629 }
   1630 
   1631 func rx_arp(pkt: *rxinfo) {
   1632 	var x: int;
   1633 
   1634 	if pkt.arp_len < 28 {
   1635 		return;
   1636 	}
   1637 
   1638 	// Hardware type
   1639 	x = (pkt.arp[0] as int << 8) + pkt.arp[1] as int;
   1640 	if x != ARP_ETHER {
   1641 		return;
   1642 	}
   1643 
   1644 	// Protocol type
   1645 	x = (pkt.arp[2] as int << 8) + pkt.arp[3] as int;
   1646 	if x != ET_IP {
   1647 		return;
   1648 	}
   1649 
   1650 	// Hardware and protocol length
   1651 	x = (pkt.arp[4] as int << 8) + pkt.arp[5] as int;
   1652 	if x != 0x0604 {
   1653 		return;
   1654 	}
   1655 
   1656 	// Operation
   1657 	pkt.arp_op = (pkt.arp[6] as int << 8) + pkt.arp[7] as int;
   1658 
   1659 	if pkt.arp_op != 1 && pkt.arp_op != 2 {
   1660 		return;
   1661 	}
   1662 
   1663 	pkt.arp_ether_src = (pkt.arp[8] as int << 40)
   1664 		+ (pkt.arp[9] as int << 32)
   1665 		+ (pkt.arp[10] as int << 24)
   1666 		+ (pkt.arp[11] as int << 16)
   1667 		+ (pkt.arp[12] as int << 8)
   1668 		+ pkt.arp[13] as int;
   1669 
   1670 	pkt.arp_ip_src = (pkt.arp[14] as int << 24)
   1671 		+ (pkt.arp[15] as int << 16)
   1672 		+ (pkt.arp[16] as int << 8)
   1673 		+ pkt.arp[17] as int;
   1674 
   1675 	pkt.arp_ether_dest = (pkt.arp[18] as int << 40)
   1676 		+ (pkt.arp[19] as int << 32)
   1677 		+ (pkt.arp[20] as int << 24)
   1678 		+ (pkt.arp[21] as int << 16)
   1679 		+ (pkt.arp[22] as int << 8)
   1680 		+ pkt.arp[23] as int;
   1681 
   1682 	pkt.arp_ip_dest = (pkt.arp[24] as int << 24)
   1683 		+ (pkt.arp[25] as int << 16)
   1684 		+ (pkt.arp[26] as int << 8)
   1685 		+ pkt.arp[27] as int;
   1686 
   1687 	handle_arp(pkt);
   1688 }
   1689 
   1690 func send_arp1(port: *realtek_port, tha: int, tpa: int) {
   1691 	var pkt: *txinfo;
   1692 	var global: *global;
   1693 	var sha: int;
   1694 	var spa: int;
   1695 	global = g();
   1696 
   1697 	sha = port.mac;
   1698 	spa = global.ip;
   1699 
   1700 	pkt = alloc_tx();
   1701 	pkt.port = port;
   1702 
   1703 	// htype
   1704 	pkt.buf[0] = 0 as byte;
   1705 	pkt.buf[1] = 1 as byte;
   1706 
   1707 	// ptype
   1708 	pkt.buf[2] = (ET_IP >> 8) as byte;
   1709 	pkt.buf[3] = (ET_IP) as byte;
   1710 
   1711 	// hlen
   1712 	pkt.buf[4] = 6 as byte;
   1713 
   1714 	// plen
   1715 	pkt.buf[5] = 4 as byte;
   1716 
   1717 	// oper
   1718 	pkt.buf[6] = 0 as byte;
   1719 	pkt.buf[7] = 1 as byte;
   1720 
   1721 	// sha
   1722 	pkt.buf[8] = (sha >> 40) as byte;
   1723 	pkt.buf[9] = (sha >> 32) as byte;
   1724 	pkt.buf[10] = (sha >> 24) as byte;
   1725 	pkt.buf[11] = (sha >> 16) as byte;
   1726 	pkt.buf[12] = (sha >> 8) as byte;
   1727 	pkt.buf[13] = sha as byte;
   1728 
   1729 	// spa
   1730 	pkt.buf[14] = (spa >> 24) as byte;
   1731 	pkt.buf[15] = (spa >> 16) as byte;
   1732 	pkt.buf[16] = (spa >> 8) as byte;
   1733 	pkt.buf[17] = spa as byte;
   1734 
   1735 	// tha
   1736 	pkt.buf[18] = (tha >> 40) as byte;
   1737 	pkt.buf[19] = (tha >> 32) as byte;
   1738 	pkt.buf[20] = (tha >> 24) as byte;
   1739 	pkt.buf[21] = (tha >> 16) as byte;
   1740 	pkt.buf[22] = (tha >> 8) as byte;
   1741 	pkt.buf[23] = tha as byte;
   1742 
   1743 	// tpa
   1744 	pkt.buf[24] = (tpa >> 24) as byte;
   1745 	pkt.buf[25] = (tpa >> 16) as byte;
   1746 	pkt.buf[26] = (tpa >> 8) as byte;
   1747 	pkt.buf[27] = tpa as byte;
   1748 
   1749 	pkt.len = 28;
   1750 
   1751 	pkt.ether_type = ET_ARP;
   1752 	pkt.ether_src = sha;
   1753 	pkt.ether_dest = tha;
   1754 
   1755 	send_ether(pkt);
   1756 
   1757 	free_tx(pkt);
   1758 }
   1759 
   1760 func find_arp(pkt: *txinfo): int {
   1761 	var flags: int;
   1762 	var global: *global;
   1763 	var mask: int;
   1764 	var now: int;
   1765 	var ret: int;
   1766 	var i: int;
   1767 	var ip: int;
   1768 	global = g();
   1769 
   1770 	if !pkt.port {
   1771 		return 0;
   1772 	}
   1773 
   1774 	ip = pkt.ip_dest;
   1775 
   1776 	// Forward to gateway if on a different network
   1777 	mask = -1 << (32 - global.ip_mask);
   1778 	if (ip & mask) != (global.ip & mask) {
   1779 		ip = global.ip_gw;
   1780 	}
   1781 
   1782 	flags = rdflags();
   1783 	cli();
   1784 
   1785 	i = 0;
   1786 	now = global.ms;
   1787 	loop {
   1788 		if i == global.arp_count {
   1789 			wrflags(flags);
   1790 			send_arp1(pkt.port, (1 << 48) - 1, ip);
   1791 			return 0;
   1792 		}
   1793 
   1794 		// Found the entry that matches
   1795 		if global.arp[i].state != 0 && global.arp[i].ip == ip {
   1796 			ret = global.arp[i].mac;
   1797 			wrflags(flags);
   1798 			return ret;
   1799 		}
   1800 
   1801 		i = i + 1;
   1802 	}
   1803 }
   1804 
   1805 func send_ip(pkt: *txinfo) {
   1806 	var id: int;
   1807 	var sum: int;
   1808 	var dest: int;
   1809 	var global: *global;
   1810 	var port: *realtek_port;
   1811 	global = g();
   1812 
   1813 	port = global.realtek_port;
   1814 	if !port {
   1815 		return;
   1816 	}
   1817 
   1818 	pkt.port = port;
   1819 
   1820 	if pkt.ip_src != global.ip {
   1821 		return;
   1822 	}
   1823 
   1824 	dest = find_arp(pkt);
   1825 	if dest == 0 {
   1826 		return;
   1827 	}
   1828 
   1829 	pkt.ether_type = ET_IP;
   1830 	pkt.ether_src = port.mac;
   1831 	pkt.ether_dest = dest;
   1832 
   1833 	pkt.buf = &pkt.buf[-20];
   1834 	pkt.len = pkt.len + 20;
   1835 
   1836 	// version + ihl
   1837 	pkt.buf[0] = 0x45 as byte;
   1838 
   1839 	// dscp
   1840 	pkt.buf[1] = 0 as byte;
   1841 
   1842 	// length
   1843 	pkt.buf[2] = (pkt.len >> 8) as byte;
   1844 	pkt.buf[3] = pkt.len as byte;
   1845 
   1846 	// identifier
   1847 	id = rand();
   1848 	pkt.buf[4] = (id >> 8) as byte;
   1849 	pkt.buf[5] = id as byte;
   1850 
   1851 	// fragment offset
   1852 	pkt.buf[6] = 0 as byte;
   1853 	pkt.buf[7] = 0 as byte;
   1854 
   1855 	// ttl
   1856 	pkt.buf[8] = 64 as byte;
   1857 	// proto
   1858 	pkt.buf[9] = pkt.ip_proto as byte;
   1859 
   1860 	// checksum
   1861 	pkt.buf[10] = 0 as byte;
   1862 	pkt.buf[11] = 0 as byte;
   1863 
   1864 	// src
   1865 	pkt.buf[12] = (pkt.ip_src >> 24) as byte;
   1866 	pkt.buf[13] = (pkt.ip_src >> 16) as byte;
   1867 	pkt.buf[14] = (pkt.ip_src >> 8) as byte;
   1868 	pkt.buf[15] = pkt.ip_src as byte;
   1869 
   1870 	// dest
   1871 	pkt.buf[16] = (pkt.ip_dest >> 24) as byte;
   1872 	pkt.buf[17] = (pkt.ip_dest >> 16) as byte;
   1873 	pkt.buf[18] = (pkt.ip_dest >> 8) as byte;
   1874 	pkt.buf[19] = pkt.ip_dest as byte;
   1875 
   1876 	sum = ~onesum(pkt.buf, 20, 0);
   1877 
   1878 	pkt.buf[10] = (sum >> 8) as byte;
   1879 	pkt.buf[11] = sum as byte;
   1880 
   1881 	send_ether(pkt);
   1882 }
   1883 
   1884 func send_icmp(pkt: *txinfo) {
   1885 	var sum: int;
   1886 
   1887 	pkt.buf = &pkt.buf[-8];
   1888 	pkt.len = pkt.len + 8;
   1889 
   1890 	pkt.buf[0] = pkt.icmp_type as byte;
   1891 	pkt.buf[1] = pkt.icmp_code as byte;
   1892 	pkt.buf[2] = 0 as byte;
   1893 	pkt.buf[3] = 0 as byte;
   1894 	pkt.buf[4] = (pkt.icmp_id >> 8) as byte;
   1895 	pkt.buf[5] = pkt.icmp_id as byte;
   1896 	pkt.buf[6] = (pkt.icmp_seq >> 8) as byte;
   1897 	pkt.buf[7] = pkt.icmp_seq as byte;
   1898 
   1899 	sum = ~onesum(pkt.buf, pkt.len, 0);
   1900 	pkt.buf[2] = (sum >> 8) as byte;
   1901 	pkt.buf[3] = sum as byte;
   1902 
   1903 	pkt.ip_proto = IP_ICMP;
   1904 
   1905 	send_ip(pkt);
   1906 }
   1907 
   1908 func send_pong(pkt: *rxinfo) {
   1909 	var global: *global;
   1910 	var tx: *txinfo;
   1911 	global = g();
   1912 	tx = alloc_tx();
   1913 	memcpy(tx.buf, pkt.icmp_seg, pkt.icmp_seg_len);
   1914 	tx.len = pkt.icmp_seg_len;
   1915 	tx.ip_src = global.ip;
   1916 	tx.ip_dest = pkt.ip_src;
   1917 	tx.icmp_type = 0;
   1918 	tx.icmp_code = 0;
   1919 	tx.icmp_id = pkt.icmp_id;
   1920 	tx.icmp_seq = pkt.icmp_seq;
   1921 	send_icmp(tx);
   1922 	free_tx(tx);
   1923 }
   1924 
   1925 func handle_icmp(pkt: *rxinfo) {
   1926 	if pkt.icmp_type == ICMP_PING {
   1927 		if pkt.icmp_code == 0 {
   1928 			send_pong(pkt);
   1929 		}
   1930 	}
   1931 }
   1932 
   1933 func rx_icmp(pkt: *rxinfo) {
   1934 	if pkt.icmp_len < 8 {
   1935 		return;
   1936 	}
   1937 
   1938 	if onesum(pkt.icmp, pkt.icmp_len, 0) != 0xffff {
   1939 		return;
   1940 	}
   1941 
   1942 	pkt.icmp_type = pkt.icmp[0] as int;
   1943 	pkt.icmp_code = pkt.icmp[1] as int;
   1944 
   1945 	pkt.icmp_id = (pkt.icmp[4] as int << 8) + pkt.icmp[5] as int;
   1946 	pkt.icmp_seq = (pkt.icmp[6] as int << 8) + pkt.icmp[7] as int;
   1947 
   1948 	pkt.icmp_seg = &pkt.icmp[8];
   1949 	pkt.icmp_seg_len = pkt.icmp_len - 8;
   1950 
   1951 	handle_icmp(pkt);
   1952 }
   1953 
   1954 func send_udp(pkt: *txinfo) {
   1955 	var sum: int;
   1956 
   1957 	pkt.ip_proto = IP_UDP;
   1958 
   1959 	pkt.buf = &pkt.buf[-8];
   1960 	pkt.len = pkt.len + 8;
   1961 
   1962 	pkt.buf[0] = (pkt.udp_src >> 8) as byte;
   1963 	pkt.buf[1] = pkt.udp_src as byte;
   1964 	pkt.buf[2] = (pkt.udp_dest >> 8) as byte;
   1965 	pkt.buf[3] = pkt.udp_dest as byte;
   1966 	pkt.buf[4] = (pkt.len >> 8) as byte;
   1967 	pkt.buf[5] = pkt.len as byte;
   1968 	pkt.buf[6] = 0 as byte;
   1969 	pkt.buf[7] = 0 as byte;
   1970 
   1971 	sum = (pkt.ip_src & 0xffff)
   1972 		+ ((pkt.ip_src >> 16) & 0xffff)
   1973 		+ (pkt.ip_dest & 0xffff)
   1974 		+ ((pkt.ip_dest >> 16) & 0xffff)
   1975 		+ IP_UDP
   1976 		+ pkt.len;
   1977 
   1978 	sum = ~onesum(pkt.buf, pkt.len, sum);
   1979 	pkt.buf[6] = (sum >> 8) as byte;
   1980 	pkt.buf[7] = sum as byte;
   1981 
   1982 	send_ip(pkt);
   1983 }
   1984 
   1985 func udp_echo(pkt: *rxinfo) {
   1986 	var tx: *txinfo;
   1987 	tx = alloc_tx();
   1988 	tx.ip_src = pkt.ip_dest;
   1989 	tx.ip_dest = pkt.ip_src;
   1990 	tx.udp_src = pkt.udp_dest;
   1991 	tx.udp_dest = pkt.udp_src;
   1992 	memcpy(tx.buf, pkt.udp_seg, pkt.udp_seg_len);
   1993 	tx.len = pkt.udp_seg_len;
   1994 	send_udp(tx);
   1995 	free_tx(tx);
   1996 }
   1997 
   1998 func handle_udp(pkt: *rxinfo) {
   1999 	if pkt.udp_dest == 8000 {
   2000 		udp_echo(pkt);
   2001 	}
   2002 }
   2003 
   2004 func rx_udp(pkt: *rxinfo) {
   2005 	var sum: int;
   2006 	var len: int;
   2007 
   2008 	if pkt.udp_len < 8 {
   2009 		return;
   2010 	}
   2011 
   2012 	len = (pkt.udp[4] as int << 8)
   2013 		+ pkt.udp[5] as int;
   2014 	if len < 8 || len > pkt.udp_len {
   2015 		return;
   2016 	}
   2017 
   2018 	pkt.udp_len = len;
   2019 
   2020 	if _r16(&pkt.udp[6]) != 0 {
   2021 		sum = onesum(pkt.udp, pkt.udp_len, pkt.ip_psum);
   2022 		if sum != 0xffff {
   2023 			return;
   2024 		}
   2025 	}
   2026 
   2027 	pkt.udp_src = (pkt.udp[0] as int << 8)
   2028 		+ pkt.udp[1] as int;
   2029 
   2030 	pkt.udp_dest = (pkt.udp[2] as int << 8)
   2031 		+ pkt.udp[3] as int;
   2032 
   2033 	pkt.udp_seg = &pkt.udp[8];
   2034 	pkt.udp_seg_len = pkt.udp_len - 8;
   2035 
   2036 	handle_udp(pkt);
   2037 }
   2038 
   2039 func send_tcp(pkt: *txinfo) {
   2040 	var len: int;
   2041 	var sum: int;
   2042 
   2043 	len = 20 + ((pkt.tcp_opt_len + 3) & -4);
   2044 
   2045 	pkt.buf = &pkt.buf[-len];
   2046 	pkt.len = pkt.len + len;
   2047 
   2048 	bzero(pkt.buf, len);
   2049 
   2050 	pkt.buf[0] = (pkt.tcp_src >> 8) as byte;
   2051 	pkt.buf[1] = pkt.tcp_src as byte;
   2052 	pkt.buf[2] = (pkt.tcp_dest >> 8) as byte;
   2053 	pkt.buf[3] = pkt.tcp_dest as byte;
   2054 
   2055 	pkt.buf[4] = (pkt.tcp_seq >> 24) as byte;
   2056 	pkt.buf[5] = (pkt.tcp_seq >> 16) as byte;
   2057 	pkt.buf[6] = (pkt.tcp_seq >> 8) as byte;
   2058 	pkt.buf[7] = pkt.tcp_seq as byte;
   2059 
   2060 	pkt.buf[8] = (pkt.tcp_ack >> 24) as byte;
   2061 	pkt.buf[9] = (pkt.tcp_ack >> 16) as byte;
   2062 	pkt.buf[10] = (pkt.tcp_ack >> 8) as byte;
   2063 	pkt.buf[11] = pkt.tcp_ack as byte;
   2064 
   2065 	pkt.buf[12] = (len << 2) as byte;
   2066 	pkt.buf[13] = pkt.tcp_flags as byte;
   2067 	pkt.buf[14] = (pkt.tcp_win >> 8) as byte;
   2068 	pkt.buf[15] = pkt.tcp_win as byte;
   2069 
   2070 	memcpy(&pkt.buf[20], pkt.tcp_opt, pkt.tcp_opt_len);
   2071 
   2072 	sum = (pkt.ip_src & 0xffff)
   2073 		+ ((pkt.ip_src >> 16) & 0xffff)
   2074 		+ (pkt.ip_dest & 0xffff)
   2075 		+ ((pkt.ip_dest >> 16) & 0xffff)
   2076 		+ IP_TCP
   2077 		+ pkt.len;
   2078 
   2079 	sum = ~onesum(pkt.buf, pkt.len, sum);
   2080 	pkt.buf[16] = (sum >> 8) as byte;
   2081 	pkt.buf[17] = sum as byte;
   2082 
   2083 	pkt.ip_proto = IP_TCP;
   2084 
   2085 	send_ip(pkt);
   2086 }
   2087 
   2088 func alloc_tcp(): *tcp_state {
   2089 	var global: *global;
   2090 	var flags: int;
   2091 	var i: int;
   2092 	var tcb: *tcp_state;
   2093 
   2094 	global = g();
   2095 
   2096 	flags = rdflags();
   2097 	cli();
   2098 
   2099 	i = 0;
   2100 	loop {
   2101 		if i == global.tcp_count {
   2102 			wrflags(flags);
   2103 			return nil;
   2104 		}
   2105 
   2106 		if !global.tcp[i] {
   2107 			tcb = alloc() as *tcp_state;
   2108 			bzero(tcb as *byte, sizeof(*tcb));
   2109 			tcb.recv_buf = alloc();
   2110 			tcb.send_buf = alloc();
   2111 			global.tcp[i] = tcb;
   2112 			wrflags(flags);
   2113 			return tcb;
   2114 		}
   2115 
   2116 		i = i + 1;
   2117 	}
   2118 }
   2119 
   2120 func tcp_free(tcb: *tcp_state) {
   2121 	var global: *global;
   2122 	var flags: int;
   2123 	var i: int;
   2124 	global = g();
   2125 	flags = rdflags();
   2126 	cli();
   2127 	i = 0;
   2128 	loop {
   2129 		if i == global.tcp_count {
   2130 			break;
   2131 		}
   2132 		if global.tcp[i] == tcb {
   2133 			global.tcp[i] = nil;
   2134 			break;
   2135 		}
   2136 		i = i + 1;
   2137 	}
   2138 	free(tcb.send_buf);
   2139 	free(tcb.recv_buf);
   2140 	free(tcb as *byte);
   2141 	wrflags(flags);
   2142 }
   2143 
   2144 func tcp_listen(port: int, event_func: func(tcb: *tcp_state)) {
   2145 	var global: *global;
   2146 	var tcb: *tcp_state;
   2147 	global = g();
   2148 
   2149 	tcb = alloc_tcp();
   2150 
   2151 	tcb.event_func = event_func;
   2152 	tcb.sock_ip = global.ip;
   2153 	tcb.sock_port = port;
   2154 
   2155 	tcb.state = TCP_LISTEN;
   2156 }
   2157 
   2158 func tcp_echo(tcb: *tcp_state) {
   2159 	var buf: *byte;
   2160 	var len: int;
   2161 
   2162 	if tcb.state == TCP_CLOSED {
   2163 		tcp_free(tcb);
   2164 		return;
   2165 	}
   2166 
   2167 	if tcb.state == TCP_CLOSE_WAIT {
   2168 		tcp_close(tcb);
   2169 		return;
   2170 	}
   2171 
   2172 	buf = alloc();
   2173 
   2174 	len = 4096 - tcb.send_len;
   2175 	len = tcp_recv(tcb, buf, len);
   2176 	if len >= 0 {
   2177 		tcp_send(tcb, buf, len);
   2178 	}
   2179 
   2180 	free(buf);
   2181 }
   2182 
   2183 func task_ssh(t: *task) {
   2184 	var tcb: *tcp_state;
   2185 	var buf: *byte;
   2186 	var c: byte;
   2187 	var n: int;
   2188 	var m: int;
   2189 	tcb = t.a as *tcp_state;
   2190 	kputs("accept\n");
   2191 	buf = alloc();
   2192 	loop {
   2193 		yield();
   2194 		if tcb.state == TCP_CLOSED {
   2195 			kputs("closed\n");
   2196 			tcp_free(tcb);
   2197 			break;
   2198 		} else if tcb.state == TCP_CLOSE_WAIT {
   2199 			if tcb.send_fin {
   2200 				continue;
   2201 			}
   2202 			kputs("close_wait\n");
   2203 			tcp_close(tcb);
   2204 			continue;
   2205 		} else if tcb.state < TCP_ESTAB {
   2206 			continue;
   2207 		}
   2208 
   2209 		// echo
   2210 		n = tcp_recv(tcb, buf, 4096);
   2211 		loop {
   2212 			m = tcp_send(tcb, buf, n);
   2213 			if n == 0 || m < 0 {
   2214 				break;
   2215 			}
   2216 			n = n - m;
   2217 			memcpy(buf, &buf[n], n);
   2218 		}
   2219 	}
   2220 	free(buf);
   2221 }
   2222 
   2223 func tcp_ssh(tcb: *tcp_state) {
   2224 	if !tcb.task {
   2225 		tcb.task = spawn(task_ssh, "sshd", tcb as *void);
   2226 	}
   2227 }
   2228 
   2229 func send_rst(pkt: *rxinfo) {
   2230 	var tx: *txinfo;
   2231 	tx = alloc_tx();
   2232 
   2233 	tx.ip_src = pkt.ip_dest;
   2234 	tx.ip_dest = pkt.ip_src;
   2235 	tx.tcp_src = pkt.tcp_dest;
   2236 	tx.tcp_dest = pkt.tcp_src;
   2237 	tx.tcp_win = 0;
   2238 	tx.tcp_opt = nil;
   2239 	tx.tcp_opt_len = 0;
   2240 	tx.len = 0;
   2241 
   2242 	if pkt.tcp_flags & TCP_ACK {
   2243 		tx.tcp_seq = pkt.tcp_ack;
   2244 		tx.tcp_ack = 0;
   2245 		tx.tcp_flags = TCP_RST;
   2246 	} else {
   2247 		tx.tcp_seq = 0;
   2248 		tx.tcp_ack = pkt.tcp_seq + pkt.tcp_seg_len;
   2249 		tx.tcp_flags = TCP_RST | TCP_ACK;
   2250 		if pkt.tcp_flags & TCP_SYN {
   2251 			tx.tcp_ack = tx.tcp_ack + 1;
   2252 		}
   2253 	}
   2254 
   2255 	send_tcp(tx);
   2256 
   2257 	free_tx(tx);
   2258 }
   2259 
   2260 func send_ack(tcb: *tcp_state) {
   2261 	var tx: *txinfo;
   2262 	tx = alloc_tx();
   2263 
   2264 	tx.ip_src = tcb.sock_ip;
   2265 	tx.ip_dest = tcb.peer_ip;
   2266 	tx.tcp_src = tcb.sock_port;
   2267 	tx.tcp_dest = tcb.peer_port;
   2268 	tx.tcp_win = 4096 - tcb.recv_len;
   2269 	tx.tcp_opt = nil;
   2270 	tx.tcp_opt_len = 0;
   2271 	tx.len = 0;
   2272 
   2273 	tx.tcp_seq = tcb.send_nxt;
   2274 	tx.tcp_ack = tcb.recv_nxt;
   2275 	tx.tcp_flags = TCP_ACK;
   2276 
   2277 	if tcb.send_len == 0 && tcb.send_fin {
   2278 		tcb.send_nxt = tcb.fin_seq;
   2279 	}
   2280 
   2281 	send_tcp(tx);
   2282 
   2283 	free_tx(tx);
   2284 }
   2285 
   2286 func send_psh(tcb: *tcp_state) {
   2287 	var tx: *txinfo;
   2288 	var len: int;
   2289 	tx = alloc_tx();
   2290 
   2291 	tx.ip_src = tcb.sock_ip;
   2292 	tx.ip_dest = tcb.peer_ip;
   2293 	tx.tcp_src = tcb.sock_port;
   2294 	tx.tcp_dest = tcb.peer_port;
   2295 	tx.tcp_win = 4096 - tcb.recv_len;
   2296 	tx.tcp_opt = nil;
   2297 	tx.tcp_opt_len = 0;
   2298 
   2299 	len = tcb.send_len;
   2300 	if len > tcb.send_wnd {
   2301 		len = tcb.send_wnd;
   2302 	}
   2303 	if len > 1460 {
   2304 		len = 1460;
   2305 	}
   2306 
   2307 	memcpy(tx.buf, tcb.send_buf, len);
   2308 	tx.len = len;
   2309 
   2310 	tx.tcp_seq = tcb.send_una;
   2311 	tx.tcp_ack = tcb.recv_nxt;
   2312 	tx.tcp_flags = TCP_ACK;
   2313 
   2314 	if tcb.state == TCP_SYN_RECV {
   2315 		tx.tcp_flags = tx.tcp_flags | TCP_SYN;
   2316 	}
   2317 
   2318 	if len > 0 {
   2319 		tx.tcp_flags = tx.tcp_flags | TCP_PSH;
   2320 	}
   2321 
   2322 	if len == tcb.send_len && tcb.send_fin {
   2323 		tx.tcp_flags = tx.tcp_flags | TCP_FIN;
   2324 
   2325 		if tcb.state == TCP_ESTAB {
   2326 			tcb.state = TCP_FIN_WAIT_1;
   2327 		} else if tcb.state == TCP_CLOSE_WAIT {
   2328 			tcb.state = TCP_LAST_ACK;
   2329 		}
   2330 
   2331 		tcb.send_nxt = tcb.fin_seq;
   2332 	} else {
   2333 		tcb.send_nxt = (tcb.send_una + len) & ((1 << 32) - 1);
   2334 	}
   2335 
   2336 	send_tcp(tx);
   2337 
   2338 	free_tx(tx);
   2339 }
   2340 
   2341 enum {
   2342 	TCP_CLOSED = 0,
   2343 	TCP_LISTEN = 1,
   2344 	TCP_SYN_SENT = 2,
   2345 	TCP_SYN_RECV = 3,
   2346 	TCP_ESTAB = 4,
   2347 	TCP_FIN_WAIT_1 = 5,
   2348 	TCP_FIN_WAIT_2 = 6,
   2349 	TCP_CLOSE_WAIT = 7,
   2350 	TCP_LAST_ACK = 8,
   2351 	TCP_CLOSING = 9,
   2352 	TCP_TIME_WAIT = 10,
   2353 }
   2354 
   2355 func find_tcb(pkt: *rxinfo): *tcp_state {
   2356 	var global: *global;
   2357 	var tcb: *tcp_state;
   2358 	var i: int;
   2359 	global = g();
   2360 
   2361 	// Find a connection
   2362 	i = 0;
   2363 	loop {
   2364 		if i == global.tcp_count {
   2365 			break;
   2366 		}
   2367 
   2368 		tcb = global.tcp[i];
   2369 
   2370 		if tcb
   2371 			&& tcb.state >= TCP_SYN_SENT
   2372 			&& tcb.peer_ip == pkt.ip_src
   2373 			&& tcb.peer_port == pkt.tcp_src
   2374 			&& tcb.sock_ip == pkt.ip_dest
   2375 			&& tcb.sock_port == pkt.tcp_dest {
   2376 			return tcb;
   2377 		}
   2378 
   2379 		i = i + 1;
   2380 	}
   2381 
   2382 	// Find a listener
   2383 	i = 0;
   2384 	loop {
   2385 		if i == global.tcp_count {
   2386 			break;
   2387 		}
   2388 
   2389 		tcb = global.tcp[i];
   2390 
   2391 		if tcb
   2392 			&& tcb.state == TCP_LISTEN
   2393 			&& tcb.sock_ip == pkt.ip_dest
   2394 			&& tcb.sock_port == pkt.tcp_dest {
   2395 			return tcb;
   2396 		}
   2397 
   2398 		i = i + 1;
   2399 	}
   2400 
   2401 	return nil;
   2402 }
   2403 
   2404 func handle_syn(tcb: *tcp_state, pkt: *rxinfo) {
   2405 	var c: *tcp_state;
   2406 	var tx: *txinfo;
   2407 
   2408 	c = alloc_tcp();
   2409 	if !c {
   2410 		send_rst(pkt);
   2411 		return;
   2412 	}
   2413 
   2414 	c.event_func = tcb.event_func;
   2415 
   2416 	c.peer_ip = pkt.ip_src;
   2417 	c.peer_port = pkt.tcp_src;
   2418 	c.sock_ip = pkt.ip_dest;
   2419 	c.sock_port = pkt.tcp_dest;
   2420 
   2421 	c.rto = 10;
   2422 
   2423 	c.send_nxt = rand();
   2424 	c.send_ack = c.send_nxt;
   2425 	c.send_una = c.send_nxt;
   2426 	c.send_wnd = pkt.tcp_win;
   2427 
   2428 	c.recv_nxt = (pkt.tcp_seq + 1) & ((1 << 32) - 1);
   2429 
   2430 	c.state = TCP_SYN_RECV;
   2431 
   2432 	tx = alloc_tx();
   2433 
   2434 	tx.ip_src = c.sock_ip;
   2435 	tx.ip_dest = c.peer_ip;
   2436 	tx.tcp_src = c.sock_port;
   2437 	tx.tcp_dest = c.peer_port;
   2438 	tx.tcp_win = 4096 - c.recv_len;
   2439 	tx.tcp_opt = nil;
   2440 	tx.tcp_opt_len = 0;
   2441 	tx.len = 0;
   2442 
   2443 	tx.tcp_flags = TCP_SYN | TCP_ACK;
   2444 	tx.tcp_seq = c.send_nxt;
   2445 	tx.tcp_ack = c.recv_nxt;
   2446 
   2447 	c.send_nxt = (c.send_nxt + 1) & ((1 << 32) - 1);
   2448 
   2449 	send_tcp(tx);
   2450 
   2451 	free_tx(tx);
   2452 }
   2453 
   2454 func handle_seg(tcb: *tcp_state, pkt: *rxinfo) {
   2455 	var offset: int;
   2456 	var wnd: int;
   2457 	var len: int;
   2458 
   2459 	// 1. Check sequence
   2460 	if pkt.tcp_seq != tcb.recv_nxt {
   2461 		if pkt.tcp_flags & TCP_RST {
   2462 			return;
   2463 		}
   2464 		send_ack(tcb);
   2465 		return;
   2466 	}
   2467 
   2468 	// 2. Check RST
   2469 	if pkt.tcp_flags & TCP_RST {
   2470 		tcb.state = TCP_CLOSED;
   2471 		return;
   2472 	}
   2473 
   2474 	// 4. Check SYN
   2475 	if pkt.tcp_flags & TCP_SYN {
   2476 		send_ack(tcb);
   2477 		return;
   2478 	}
   2479 
   2480 	// 5. Check ACK
   2481 	if pkt.tcp_flags & TCP_ACK == 0 {
   2482 		return;
   2483 	}
   2484 
   2485 	// Validate ACK
   2486 	offset = (pkt.tcp_ack - tcb.send_una) & ((1 << 31) - 1);
   2487 	wnd = (tcb.send_nxt - tcb.send_una) & ((1 << 31) - 1);
   2488 	if offset > wnd {
   2489 		send_ack(tcb);
   2490 		return;
   2491 	}
   2492 
   2493 	if tcb.state == TCP_SYN_RECV {
   2494 		tcb.state = TCP_ESTAB;
   2495 		tcb.send_una = (tcb.send_una + 1) & ((1 << 32) - 1);
   2496 	}
   2497 
   2498 	if tcb.state == TCP_FIN_WAIT_1 && tcb.send_una == tcb.send_nxt {
   2499 		tcb.state = TCP_FIN_WAIT_2;
   2500 	}
   2501 
   2502 	if tcb.state == TCP_CLOSING && tcb.send_una == tcb.send_nxt {
   2503 		tcb.state = TCP_TIME_WAIT;
   2504 	}
   2505 
   2506 	if tcb.state == TCP_LAST_ACK {
   2507 		tcb.state = TCP_CLOSED;
   2508 		return;
   2509 	}
   2510 
   2511 	len = (pkt.tcp_ack - tcb.send_una) & ((1 << 31) - 1);
   2512 	if len > tcb.send_len {
   2513 		len = tcb.send_len;
   2514 	}
   2515 	tcb.send_len = tcb.send_len - len;
   2516 	memcpy(tcb.send_buf, &tcb.send_buf[len], tcb.send_len);
   2517 
   2518 	tcb.send_una = pkt.tcp_ack;
   2519 
   2520 	// 7. Process data
   2521 	if pkt.tcp_seg_len > 0 {
   2522 		len = 4096 - tcb.recv_len;
   2523 		if len > pkt.tcp_seg_len {
   2524 			len = pkt.tcp_seg_len;
   2525 		}
   2526 
   2527 		memcpy(&tcb.recv_buf[tcb.recv_len], pkt.tcp_seg, len);
   2528 		tcb.recv_nxt = (tcb.recv_nxt + len) & ((1 << 32) - 1);
   2529 		tcb.recv_len = tcb.recv_len + len;
   2530 		send_ack(tcb);
   2531 	}
   2532 
   2533 	// 8. Check FIN
   2534 	if pkt.tcp_flags & TCP_FIN {
   2535 		tcb.recv_nxt = (tcb.recv_nxt + len + 1) & ((1 << 32) - 1);
   2536 
   2537 		if tcb.state == TCP_SYN_RECV || tcb.state == TCP_ESTAB {
   2538 			tcb.state = TCP_CLOSE_WAIT;
   2539 		}
   2540 
   2541 		if tcb.state == TCP_FIN_WAIT_1 {
   2542 			if tcb.send_una == tcb.send_nxt {
   2543 				tcb.state = TCP_TIME_WAIT;
   2544 			} else {
   2545 				tcb.state = TCP_CLOSING;
   2546 			}
   2547 		}
   2548 
   2549 		if tcb.state == TCP_FIN_WAIT_2 {
   2550 			tcb.state = TCP_TIME_WAIT;
   2551 		}
   2552 	}
   2553 
   2554 	if tcb.state == TCP_TIME_WAIT {
   2555 		tcb.deadline = 300000;
   2556 	}
   2557 }
   2558 
   2559 func tcp_tick(tcb: *tcp_state) {
   2560 	var global: *global;
   2561 	var len: int;
   2562 	global = g();
   2563 
   2564 	if tcb.state == TCP_TIME_WAIT {
   2565 		kputc('.');
   2566 		return;
   2567 	}
   2568 
   2569 	if tcb.state <= TCP_LISTEN || (!tcb.send_fin && !tcb.send_len) {
   2570 		return;
   2571 	}
   2572 
   2573 	// We got an ack send a new packet
   2574 	if tcb.send_ack != tcb.send_una {
   2575 		tcb.send_ack = tcb.send_una;
   2576 		if tcb.send_len || tcb.send_fin {
   2577 			send_psh(tcb);
   2578 		}
   2579 		tcb.rto = 10;
   2580 		tcb.deadline = tcb.rto;
   2581 		return;
   2582 	}
   2583 
   2584 	// Consider retransmission
   2585 	if tcb.deadline > 0 {
   2586 		tcb.deadline = tcb.deadline - 1;
   2587 		return;
   2588 	}
   2589 
   2590 	tcb.rto = tcb.rto * 2;
   2591 	if tcb.rto > 10000 {
   2592 		tcb.rto = 10000;
   2593 	}
   2594 
   2595 	send_psh(tcb);
   2596 	tcb.deadline = tcb.rto;
   2597 }
   2598 
   2599 func tcp_send(tcb: *tcp_state, b: *byte, n: int): int {
   2600 	var cap: int;
   2601 	var flags: int;
   2602 	flags = rdflags();
   2603 	cli();
   2604 
   2605 	if tcb.state != TCP_ESTAB || n < 0 {
   2606 		wrflags(flags);
   2607 		return -1;
   2608 	}
   2609 
   2610 	cap = 4096 - tcb.send_len;
   2611 	if n > cap {
   2612 		n = cap;
   2613 	}
   2614 
   2615 	memcpy(&tcb.send_buf[tcb.send_len], b, n);
   2616 	tcb.send_len = tcb.send_len + n;
   2617 
   2618 	wrflags(flags);
   2619 	return n;
   2620 }
   2621 
   2622 func tcp_recv(tcb: *tcp_state, b: *byte, n: int): int {
   2623 	var cap: int;
   2624 	var flags: int;
   2625 	flags = rdflags();
   2626 	cli();
   2627 
   2628 	if (tcb.state != TCP_ESTAB && tcb.recv_len == 0) || n < 0 {
   2629 		wrflags(flags);
   2630 		return 0;
   2631 	}
   2632 
   2633 	if n > tcb.recv_len {
   2634 		n = tcb.recv_len;
   2635 	}
   2636 
   2637 	memcpy(b, tcb.recv_buf, n);
   2638 	tcb.recv_len = tcb.recv_len - n;
   2639 	memcpy(tcb.recv_buf, &tcb.recv_buf[n], tcb.recv_len);
   2640 
   2641 	wrflags(flags);
   2642 	return n;
   2643 }
   2644 
   2645 func tcp_close(tcb: *tcp_state) {
   2646 	var flags: int;
   2647 	flags = rdflags();
   2648 	cli();
   2649 
   2650 	tcb.send_fin = 1;
   2651 	tcb.fin_seq = (tcb.send_una + tcb.send_len + 1) & ((1 << 32) - 1);
   2652 
   2653 	wrflags(flags);
   2654 }
   2655 
   2656 func handle_tcp(pkt: *rxinfo) {
   2657 	var tcb: *tcp_state;
   2658 
   2659 	if pkt.tcp_src == 0 || pkt.tcp_dest == 0 {
   2660 		return;
   2661 	}
   2662 
   2663 	// Find state for the incoming packet
   2664 	tcb = find_tcb(pkt);
   2665 	if !tcb || tcb.state == TCP_CLOSED {
   2666 		send_rst(pkt);
   2667 	} else if tcb.state == TCP_LISTEN {
   2668 		// Handle incoming connection
   2669 		if pkt.tcp_flags & TCP_RST {
   2670 			return;
   2671 		}
   2672 
   2673 		if pkt.tcp_flags & TCP_ACK {
   2674 			send_rst(pkt);
   2675 			return;
   2676 		}
   2677 
   2678 		if pkt.tcp_flags & (TCP_FIN|TCP_SYN|TCP_PSH) != TCP_SYN {
   2679 			return;
   2680 		}
   2681 
   2682 		handle_syn(tcb, pkt);
   2683 	} else if tcb.state == TCP_SYN_SENT {
   2684 		// out going connections not implemented yet
   2685 		send_rst(pkt);
   2686 	} else {
   2687 		handle_seg(tcb, pkt);
   2688 		if tcb.state != TCP_LISTEN {
   2689 			tcb.event_func(tcb);
   2690 		}
   2691 	}
   2692 }
   2693 
   2694 enum {
   2695 	TCP_ACK = 16,
   2696 	TCP_PSH = 8,
   2697 	TCP_RST = 4,
   2698 	TCP_SYN = 2,
   2699 	TCP_FIN = 1,
   2700 }
   2701 
   2702 func rx_tcp(pkt: *rxinfo) {
   2703 	var sum: int;
   2704 	var off: int;
   2705 
   2706 	if pkt.tcp_len < 20 {
   2707 		return;
   2708 	}
   2709 
   2710 	sum = onesum(pkt.tcp, pkt.tcp_len, pkt.ip_psum);
   2711 	if sum != 0xffff {
   2712 		return;
   2713 	}
   2714 
   2715 	pkt.tcp_src = (pkt.tcp[0] as int << 8)
   2716 		+ pkt.tcp[1] as int;
   2717 	pkt.tcp_dest = (pkt.tcp[2] as int << 8)
   2718 		+ pkt.tcp[3] as int;
   2719 	pkt.tcp_seq = (pkt.tcp[4] as int << 24)
   2720 		+ (pkt.tcp[5] as int << 16)
   2721 		+ (pkt.tcp[6] as int << 8)
   2722 		+ pkt.tcp[7] as int;
   2723 	pkt.tcp_ack = (pkt.tcp[8] as int << 24)
   2724 		+ (pkt.tcp[9] as int << 16)
   2725 		+ (pkt.tcp[10] as int << 8)
   2726 		+ pkt.tcp[11] as int;
   2727 	pkt.tcp_flags = pkt.tcp[13] as int;
   2728 	pkt.tcp_win = (pkt.tcp[14] as int << 8)
   2729 		+ pkt.tcp[15] as int;
   2730 
   2731 	off = (pkt.tcp[12] as int >> 4) << 2;
   2732 	if off < 20 || off > pkt.tcp_len {
   2733 		return;
   2734 	}
   2735 
   2736 	pkt.tcp_opt = &pkt.tcp[20];
   2737 	pkt.tcp_opt_len = off - 20;
   2738 
   2739 	pkt.tcp_seg = &pkt.tcp[off];
   2740 	pkt.tcp_seg_len = pkt.tcp_len - off;
   2741 
   2742 	handle_tcp(pkt);
   2743 }
   2744 
   2745 func rx_ip(pkt: *rxinfo) {
   2746 	var global: *global;
   2747 	var len: int;
   2748 	var frag: int;
   2749 
   2750 	global = g();
   2751 
   2752 	if pkt.ip_len < 20 {
   2753 		return;
   2754 	}
   2755 
   2756 	if onesum(pkt.ip, 20, 0) != 0xffff {
   2757 		return;
   2758 	}
   2759 
   2760 	if pkt.ip[0] != 0x45 as byte {
   2761 		return;
   2762 	}
   2763 
   2764 	len = (pkt.ip[2] as int << 8)
   2765 		+ pkt.ip[3] as int;
   2766 	if len < 20 || len > pkt.ip_len {
   2767 		return;
   2768 	}
   2769 	pkt.ip_len = len;
   2770 
   2771 	frag = (pkt.ip[6] as int << 8)
   2772 		+ pkt.ip[7] as int;
   2773 
   2774 	if frag & (1 << 15) != 0 || frag & 8191 != 0 {
   2775 		return;
   2776 	}
   2777 
   2778 	pkt.ip_proto = pkt.ip[9] as int;
   2779 
   2780 	pkt.ip_src = (pkt.ip[12] as int << 24)
   2781 		+ (pkt.ip[13] as int << 16)
   2782 		+ (pkt.ip[14] as int << 8)
   2783 		+ pkt.ip[15] as int;
   2784 	pkt.ip_dest = (pkt.ip[16] as int << 24)
   2785 		+ (pkt.ip[17] as int << 16)
   2786 		+ (pkt.ip[18] as int << 8)
   2787 		+ pkt.ip[19] as int;
   2788 
   2789 	// Pesudo header sum
   2790 	pkt.ip_psum = (pkt.ip_src & 0xffff)
   2791 		+ ((pkt.ip_src >> 16) & 0xffff)
   2792 		+ (pkt.ip_dest & 0xffff)
   2793 		+ ((pkt.ip_dest >> 16) & 0xffff)
   2794 		+ pkt.ip_proto
   2795 		+ (pkt.ip_len - 20);
   2796 
   2797 	memo_arp(pkt.ether_src, pkt.ip_src, 1);
   2798 
   2799 	if pkt.ip_dest != global.ip {
   2800 		return;
   2801 	}
   2802 
   2803 	if pkt.ip_proto == IP_ICMP {
   2804 		pkt.icmp = &pkt.ip[20];
   2805 		pkt.icmp_len = pkt.ip_len - 20;
   2806 		rx_icmp(pkt);
   2807 	} else if pkt.ip_proto == IP_TCP {
   2808 		pkt.tcp = &pkt.ip[20];
   2809 		pkt.tcp_len = pkt.ip_len - 20;
   2810 		rx_tcp(pkt);
   2811 	} else if pkt.ip_proto == IP_UDP {
   2812 		pkt.udp = &pkt.ip[20];
   2813 		pkt.udp_len = pkt.ip_len - 20;
   2814 		rx_udp(pkt);
   2815 	}
   2816 }
   2817 
   2818 func rx_ether(pkt: *rxinfo) {
   2819 	if pkt.ether_len < 14 {
   2820 		return;
   2821 	}
   2822 
   2823 	pkt.ether_dest = (pkt.ether[0] as int << 40)
   2824 		+ (pkt.ether[1] as int << 32)
   2825 		+ (pkt.ether[2] as int << 24)
   2826 		+ (pkt.ether[3] as int << 16)
   2827 		+ (pkt.ether[4] as int << 8)
   2828 		+ pkt.ether[5] as int;
   2829 	pkt.ether_src = (pkt.ether[6] as int << 40)
   2830 		+ (pkt.ether[7] as int << 32)
   2831 		+ (pkt.ether[8] as int << 24)
   2832 		+ (pkt.ether[9] as int << 16)
   2833 		+ (pkt.ether[10] as int << 8)
   2834 		+ pkt.ether[11] as int;
   2835 	pkt.ether_type = (pkt.ether[12] as int << 8)
   2836 		+ (pkt.ether[13] as int);
   2837 
   2838 	if pkt.ether_type == ET_ARP {
   2839 		pkt.arp = &pkt.ether[14];
   2840 		pkt.arp_len = pkt.ether_len - 14;
   2841 		rx_arp(pkt);
   2842 	} else if pkt.ether_type == ET_IP {
   2843 		pkt.ip = &pkt.ether[14];
   2844 		pkt.ip_len = pkt.ether_len - 14;
   2845 		rx_ip(pkt);
   2846 	}
   2847 }
   2848 
   2849 func isr_realtek() {
   2850 	var pkt: rxinfo;
   2851 	var global: *global;
   2852 	var port: *realtek_port;
   2853 	var i: int;
   2854 	var packet: *byte;
   2855 	var len: int;
   2856 
   2857 	global = g();
   2858 
   2859 	port = global.realtek_port;
   2860 	loop {
   2861 		if !port {
   2862 			break;
   2863 		}
   2864 
   2865 		// clear interrupt flags
   2866 		outw(port.io + 0x3e, 0xffff);
   2867 
   2868 		i = 0;
   2869 		loop {
   2870 			if i == port.rx.count {
   2871 				break;
   2872 			}
   2873 
   2874 			if port.rx.ring[i].flags & (1 << 31) == 0 {
   2875 				pkt.port = port;
   2876 				pkt.ether = ptov(port.rx.ring[i].framep);
   2877 				pkt.ether_len = port.rx.ring[i].flags & 4095;
   2878 
   2879 				if pkt.ether_len >= 4 {
   2880 					pkt.ether_len = pkt.ether_len - 4;
   2881 				}
   2882 
   2883 				rx_ether(&pkt);
   2884 
   2885 				port.rx.ring[i].flags = (1 << 31) + (((i + 1) == port.rx.count) << 30) + 4095;
   2886 			}
   2887 
   2888 			i = i + 1;
   2889 		}
   2890 
   2891 		port = port.next;
   2892 	}
   2893 }
   2894 
   2895 func init_ahci(dev: *pcidev) {
   2896 	var global: *global;
   2897 	var ahci: *byte;
   2898 
   2899 	global = g();
   2900 
   2901 	if dev.cls != 1 || dev.subcls != 6 {
   2902 		return;
   2903 	}
   2904 
   2905 	ahci = map_pci(dev.bar5);
   2906 
   2907 	// Enable dma
   2908 	_w16(&dev.addr[4], 6);
   2909 
   2910 	// Enable message signaled interrupts
   2911 	_w16(&dev.msi[8], 34);
   2912 	_w32(&dev.msi[4], global.lapicp);
   2913 	_w16(&dev.msi[2], 0x0001);
   2914 
   2915 	// Find populated ports
   2916 	if _r32(&ahci[0x00]) & (1 << 31) == 0 {
   2917 		kputs("AHCI does not support 64 bit dma\n");
   2918 		return;
   2919 	}
   2920 
   2921 	// Enable ahci and interrupts
   2922 	_w32(&ahci[0x4], (1 << 31) + (1 << 1));
   2923 	_w32(&ahci[0x08], -1);
   2924 
   2925 	var pi: int;
   2926 	var i: int;
   2927 
   2928 	pi = _r32(&ahci[0xc]);
   2929 	i = 0;
   2930 	loop {
   2931 		if pi == 0 {
   2932 			break;
   2933 		}
   2934 
   2935 		if pi & 1 {
   2936 			init_ahci_port(ahci, i);
   2937 		}
   2938 
   2939 		pi = pi >> 1;
   2940 		i = i + 1;
   2941 	}
   2942 }
   2943 
   2944 struct ahci_port {
   2945 	next: *ahci_port;
   2946 	ahci: *byte;
   2947 	port: *byte;
   2948 	cmd: *byte;
   2949 	ctabp: int;
   2950 	ctab: *byte;
   2951 	fis: *byte;
   2952 	bufp: int;
   2953 	buf: *byte;
   2954 }
   2955 
   2956 func init_ahci_port(ahci: *byte, i: int) {
   2957 	var global: *global;
   2958 	var port: *byte;
   2959 
   2960 	global = g();
   2961 
   2962 	port = &ahci[0x100 + 0x80 * i];
   2963 
   2964 	// Set ST=0
   2965 	_w32(&port[0x18], _r32(&port[0x18]) & -2 & ~(15 << 28));
   2966 
   2967 	// Wait for DMA finish
   2968 	loop {
   2969 		if _r32(&port[0x18]) & (1 << 15) == 0 {
   2970 			break;
   2971 		}
   2972 	}
   2973 
   2974 	// Clear errors
   2975 	_w32(&port[0x30], -1);
   2976 
   2977 	var ahci_port: *ahci_port;
   2978 	ahci_port = ptov(alloc_page()) as *ahci_port;
   2979 	ahci_port.next = nil;
   2980 	ahci_port.ahci = ahci;
   2981 	ahci_port.port = port;
   2982 
   2983 	// Allocate queues
   2984 	var cmdp: int;
   2985 	var fisp: int;
   2986 	var ctabp: int;
   2987 
   2988 	// each command list header is 32 bytes, there are 32 of them
   2989 	cmdp = alloc_page();
   2990 	ahci_port.cmd = ptov(cmdp);
   2991 	bzero(ahci_port.cmd, 4096);
   2992 
   2993 	//// each table must be aligned to 128 bytes
   2994 	//// allocate one 128 block to each command list from this page
   2995 	ctabp = alloc_page();
   2996 	ahci_port.ctabp = ctabp;
   2997 	ahci_port.ctab = ptov(ctabp);
   2998 	bzero(ahci_port.ctab, 4096);
   2999 
   3000 	//// fis is 256 bytes
   3001 	fisp = alloc_page();
   3002 	ahci_port.fis = ptov(fisp);
   3003 	bzero(ahci_port.fis, 4096);
   3004 
   3005 	// Set command list and fis pointers
   3006 	_w32(&port[0x00], cmdp);
   3007 	_w32(&port[0x04], cmdp >> 32);
   3008 	_w32(&port[0x08], fisp);
   3009 	_w32(&port[0x0c], fisp >> 32);
   3010 
   3011 	// Spin up device
   3012 	_w32(&port[0x18], 0x11);
   3013 
   3014 	// Wait for busy and drq to clear
   3015 	loop {
   3016 		if _r32(&port[0x20]) & 0x88 == 0 {
   3017 			break;
   3018 		}
   3019 	}
   3020 
   3021 	// Enable interrupts
   3022 	_w32(&port[0x14], -1);
   3023 	_w32(&port[0x10], -1);
   3024 
   3025 	// Send ATA IDENTIFY
   3026 	ahci_port.bufp = alloc_page();
   3027 	ahci_port.buf = ptov(ahci_port.bufp);
   3028 
   3029 	// Set AHCI Doorbell
   3030 	//bzero(ahci_port.buf, 4096);
   3031 	//fill_fis_h2d(ahci_port, ATA_READ, 0);
   3032 	//_w32(&ahci_port.port[0x38], 1);
   3033 
   3034 	ahci_port.next = global.ahci_port;
   3035 	global.ahci_port = ahci_port;
   3036 }
   3037 
   3038 enum {
   3039 	ATA_IDENTIFY = 0xec,
   3040 	ATA_READ = 0x25,
   3041 	ATA_WRITE = 0x35,
   3042 }
   3043 
   3044 func fill_fis_h2d(ahci_port: *ahci_port, cmd: int, lba: int) {
   3045 	var w: int;
   3046 	var size: int;
   3047 
   3048 	size = 4096;
   3049 	if cmd == ATA_IDENTIFY {
   3050 		size = 512;
   3051 	}
   3052 
   3053 	bzero(ahci_port.cmd, 4096);
   3054 
   3055 	w = (cmd == ATA_WRITE);
   3056 
   3057 	// Set command list header: prd_count + cmd + write + cmd_words
   3058 	_w32(&ahci_port.cmd[0x00], (1 << 16) + (1 << 10) + (w << 6) + 5);
   3059 	_w32(&ahci_port.cmd[0x04], 0);
   3060 	_w32(&ahci_port.cmd[0x08], ahci_port.ctabp);
   3061 	_w32(&ahci_port.cmd[0x0c], ahci_port.ctabp >> 32);
   3062 
   3063 	bzero(ahci_port.ctab, 4096);
   3064 
   3065 	// Fill command FIS
   3066 	ahci_port.ctab[0] = 0x27 as byte;
   3067 	ahci_port.ctab[1] = 0x80 as byte;
   3068 	ahci_port.ctab[2] = cmd as byte;
   3069 	ahci_port.ctab[3] = 0 as byte;
   3070 
   3071 	ahci_port.ctab[4] = lba as byte;
   3072 	ahci_port.ctab[5] = (lba >> 8) as byte;
   3073 	ahci_port.ctab[6] = (lba >> 16) as byte;
   3074 	ahci_port.ctab[7] = (1 << 6) as byte;
   3075 
   3076 	ahci_port.ctab[8] = (lba >> 24) as byte;
   3077 	ahci_port.ctab[9] = (lba >> 32) as byte;
   3078 	ahci_port.ctab[10] = (lba >> 40) as byte;
   3079 	ahci_port.ctab[11] = 0 as byte;
   3080 
   3081 	// Count of sectors
   3082 	ahci_port.ctab[12] = (size >> 9) as byte;
   3083 	ahci_port.ctab[13] = (size >> 17) as byte;
   3084 	ahci_port.ctab[14] = 0 as byte;
   3085 	ahci_port.ctab[15] = 0 as byte;
   3086 
   3087 	ahci_port.ctab[16] = 0 as byte;
   3088 	ahci_port.ctab[17] = 0 as byte;
   3089 	ahci_port.ctab[18] = 0 as byte;
   3090 	ahci_port.ctab[19] = 0 as byte;
   3091 
   3092 	// Fill PRDT
   3093 	_w32(&ahci_port.ctab[0x80], ahci_port.bufp);
   3094 	_w32(&ahci_port.ctab[0x84], ahci_port.bufp >> 32);
   3095 	_w32(&ahci_port.ctab[0x88], 0);
   3096 	_w32(&ahci_port.ctab[0x8c], (1 << 31) + (size - 1));
   3097 }
   3098 
   3099 func isr_ahci() {
   3100 	var global: *global;
   3101 	var ahci_port: *ahci_port;
   3102 	var i: int;
   3103 
   3104 	global = g();
   3105 
   3106 	ahci_port = global.ahci_port;
   3107 	loop {
   3108 		if !ahci_port {
   3109 			break;
   3110 		}
   3111 
   3112 		_w32(&ahci_port.port[0x10], -1);
   3113 
   3114 		ahci_port = ahci_port.next;
   3115 	}
   3116 }
   3117 
   3118 func tick(r: *regs) {
   3119 	var global: *global;
   3120 	var tcb: *tcp_state;
   3121 	var cur: *task;
   3122 	var next: *task;
   3123 	var i: int;
   3124 	global = g();
   3125 
   3126 	global.ms = global.ms + 1;
   3127 
   3128 	i = 0;
   3129 	loop {
   3130 		if i == global.tcp_count {
   3131 			break;
   3132 		}
   3133 
   3134 		tcb = global.tcp[i];
   3135 		if tcb {
   3136 			tcp_tick(tcb);
   3137 			if tcb.state != TCP_LISTEN {
   3138 				tcb.event_func(tcb);
   3139 			}
   3140 		}
   3141 
   3142 		i = i + 1;
   3143 	}
   3144 
   3145 	// round robin schedule
   3146 	cur = global.curtask;
   3147 	memcpy((&cur.regs) as *byte, r as *byte, sizeof(*r));
   3148 
   3149 	schedule();
   3150 
   3151 	next = global.curtask;
   3152 	memcpy(r as *byte, (&next.regs) as *byte, sizeof(*r));
   3153 }
   3154 
   3155 func freept(pt: int) {
   3156 	free(ptov(pt));
   3157 }
   3158 
   3159 func free_task(t: *task) {
   3160 	var i: int;
   3161 	i = 0;
   3162 	loop {
   3163 		if i == 512 {
   3164 			break;
   3165 		}
   3166 		if t.files[i] {
   3167 			vclose(t.files[i]);
   3168 			t.files[i] = nil;
   3169 		}
   3170 		i = i + 1;
   3171 	}
   3172 	vclose(t.cwd);
   3173 	freept(t.pt);
   3174 	free(t.stack);
   3175 	free(t as *byte);
   3176 }
   3177 
   3178 func schedule() {
   3179 	var global: *global;
   3180 	var cur: *task;
   3181 	var next: *task;
   3182 	var prev: *task;
   3183 	var dead: *task;
   3184 	global = g();
   3185 
   3186 	cur = global.curtask;
   3187 	next = cur.next;
   3188 	loop {
   3189 		if !next.dead {
   3190 			break;
   3191 		}
   3192 		dead = next;
   3193 		next = dead.next;
   3194 		prev = dead.prev;
   3195 		if dead == cur {
   3196 			continue;
   3197 		}
   3198 		prev.next = next;
   3199 		next.prev = prev;
   3200 		free_task(dead);
   3201 	}
   3202 	global.curtask = next;
   3203 	invlpt();
   3204 }
   3205 
   3206 func task_exit() {
   3207 	var global: *global;
   3208 	var t: *task;
   3209 	global = g();
   3210 	t = global.curtask;
   3211 	cli();
   3212 	loop {
   3213 		t.dead = 1;
   3214 		yield();
   3215 	}
   3216 }
   3217 
   3218 func yield() {
   3219 	var global: *global;
   3220 	var flags: int;
   3221 	var cur: *task;
   3222 	var next: *task;
   3223 	global = g();
   3224 	flags = rdflags();
   3225 	cli();
   3226 
   3227 	cur = global.curtask;
   3228 	schedule();
   3229 	next = global.curtask;
   3230 
   3231 	taskswitch(&cur.regs, &next.regs);
   3232 	wrflags(flags);
   3233 }
   3234 
   3235 func kdie(msg: *byte) {
   3236 	kputs("die: ");
   3237 	kputs(msg);
   3238 	kputs("\n");
   3239 	cli();
   3240 	loop {
   3241 		hlt();
   3242 	}
   3243 }
   3244 
   3245 func sleep(ms: int) {
   3246 	var global: *global;
   3247 	var deadline: int;
   3248 
   3249 	global = g();
   3250 
   3251 	if ms <= 0 {
   3252 		return;
   3253 	}
   3254 
   3255 	if rdflags() & 0x200 == 0 {
   3256 		kdie("attempt to sleep with interrupts disabled");
   3257 	}
   3258 
   3259 	deadline = global.ms + ms;
   3260 	loop {
   3261 		if global.ms > deadline {
   3262 			break;
   3263 		}
   3264 		hlt();
   3265 	}
   3266 }
   3267 
   3268 func xxd(data: *byte, len: int) {
   3269 	var i: int;
   3270 	var j: int;
   3271 	loop {
   3272 		if i >= len {
   3273 			break;
   3274 		}
   3275 
   3276 		kputh32(i);
   3277 
   3278 		kputc(':');
   3279 		kputc(' ');
   3280 
   3281 		j = 0;
   3282 
   3283 		loop {
   3284 			if j == 16 {
   3285 				break;
   3286 			}
   3287 
   3288 			if i + j < len {
   3289 				kputh8(data[i + j] as int);
   3290 			} else {
   3291 				kputc(' ');
   3292 				kputc(' ');
   3293 			}
   3294 
   3295 			if i + j + 1 < len {
   3296 				kputh8(data[i + j + 1] as int);
   3297 			} else {
   3298 				kputc(' ');
   3299 				kputc(' ');
   3300 			}
   3301 
   3302 			kputc(' ');
   3303 
   3304 			j = j + 2;
   3305 		}
   3306 
   3307 		kputc(' ');
   3308 
   3309 		j = 0;
   3310 		loop {
   3311 			if j == 16 || i + j >= len {
   3312 				break;
   3313 			}
   3314 
   3315 			if data[i + j] as int >= 0x20 && data[i + j] as int < 0x80 {
   3316 				kputc(data[i + j] as int);
   3317 			} else {
   3318 				kputc('.');
   3319 			}
   3320 
   3321 			j = j + 1;
   3322 		}
   3323 
   3324 		kputc('\n');
   3325 
   3326 		i = i + 16;
   3327 	}
   3328 }
   3329 
   3330 func read_cmos(a: int): int {
   3331 	outb(0x70, (a & 0x7f) | 0x80);
   3332 	return inb(0x71);
   3333 }
   3334 
   3335 func read_rtc() {
   3336 	var global: *global;
   3337 	var epoch_time: int;
   3338 	var days_since_epoch: int;
   3339 	var sec: int;
   3340 	var min: int;
   3341 	var hour: int;
   3342 	var day: int;
   3343 	var mon: int;
   3344 	var year: int;
   3345 	var flags: int;
   3346 	var days_in_month: *byte;
   3347 	global = g();
   3348 
   3349 	sec = 0;
   3350 	min = 0;
   3351 	hour = 0;
   3352 	day = 0;
   3353 	mon = 0;
   3354 	year = 0;
   3355 	flags = 0;
   3356 
   3357 	loop {
   3358 		if read_cmos(0xa) & 0x80 {
   3359 			continue;
   3360 		}
   3361 
   3362 		if read_cmos(0x00) != sec {
   3363 			sec = read_cmos(0x00);
   3364 			continue;
   3365 		}
   3366 
   3367 		if read_cmos(0x02) != min {
   3368 			min = read_cmos(0x02);
   3369 			continue;
   3370 		}
   3371 
   3372 		if read_cmos(0x04) != hour {
   3373 			hour = read_cmos(0x04);
   3374 			continue;
   3375 		}
   3376 
   3377 		if read_cmos(0x07) != day {
   3378 			day = read_cmos(0x07);
   3379 			continue;
   3380 		}
   3381 
   3382 		if read_cmos(0x08) != mon {
   3383 			mon = read_cmos(0x08);
   3384 			continue;
   3385 		}
   3386 
   3387 		if read_cmos(0x09) != year {
   3388 			year = read_cmos(0x09);
   3389 			continue;
   3390 		}
   3391 
   3392 		if read_cmos(0x0b) != flags {
   3393 			flags = read_cmos(0x0b);
   3394 			continue;
   3395 		}
   3396 
   3397 		break;
   3398 	}
   3399 
   3400 	// bcd -> binary
   3401 	if flags & 0x04 == 0 {
   3402 		sec = (sec & 15) + (((sec >> 4) & 15) * 10);
   3403 		min = (min & 15) + (((min >> 4) & 15) * 10);
   3404 		hour = (hour & 15) + (((hour >> 4) & 15) * 10) + (hour & 0x80);
   3405 		day = (day & 15) + (((day >> 4) & 15) * 10);
   3406 		mon = (mon & 15) + (((mon >> 4) & 15) * 10);
   3407 		year = (year & 15) + (((year >> 4) & 15) * 10);
   3408 	}
   3409 
   3410 	// 12 hour clock
   3411 	if flags & 0x02 == 0 && hour & 0x80 {
   3412 		hour = ((hour & 0x7f) + 12) % 24;
   3413 	}
   3414 
   3415 	// Current century
   3416 	year = year + 2000;
   3417 
   3418 	days_since_epoch = year * 365
   3419 		+ (year / 4)
   3420 		- (year / 100)
   3421 		+ (year / 400)
   3422 		+ (day - 1)
   3423 		- 719527;
   3424 
   3425 	if (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0) {
   3426 		days_in_month = " 313232332323";
   3427 	} else {
   3428 		days_in_month = " 303232332323";
   3429 	}
   3430 
   3431 	var i: int;
   3432 	i = 1;
   3433 	loop {
   3434 		if i >= mon {
   3435 			break;
   3436 		}
   3437 
   3438 		days_since_epoch = days_since_epoch + (days_in_month[i] as int - '0' + 28);
   3439 
   3440 		i = i + 1;
   3441 	}
   3442 
   3443 	epoch_time = days_since_epoch * 86400 + hour * 3600 + min * 60 + sec;
   3444 
   3445 	global.boot_time = epoch_time;
   3446 }
   3447 
   3448 func _tstart() {
   3449 	var global: *global;
   3450 	var t: *task;
   3451 	global = g();
   3452 	t = global.curtask;
   3453 	sti();
   3454 	t.f(t);
   3455 	task_exit();
   3456 }
   3457 
   3458 func spawn(f: (func(t: *task)), name: *byte, a: *void): *task {
   3459 	var global: *global;
   3460 	var t: *task;
   3461 	var cur: *task;
   3462 	var next: *task;
   3463 	var flags: int;
   3464 	global = g();
   3465 	t = alloc() as *task;
   3466 	bzero(t as *byte, sizeof(*t));
   3467 	t.files = alloc() as **vfile;
   3468 	bzero(t.files as *byte, 4096);
   3469 	t.stack = alloc();
   3470 	bzero(t.stack, 4096);
   3471 	t.name = name;
   3472 	t.regs.rsp = (t.stack as int) + 4096;
   3473 	t.regs.rip = _tstart as int;
   3474 	t.regs.cs = 8;
   3475 	t.regs.ss = 16;
   3476 	t.f = f;
   3477 	t.a = a;
   3478 	t.pt = alloc_page();
   3479 	bzero(ptov(t.pt), 4096);
   3480 	flags = rdflags();
   3481 	cli();
   3482 	cur = global.curtask;
   3483 	t.cwd = vdup(cur.cwd);
   3484 	next = cur.next;
   3485 	t.next = next;
   3486 	t.prev = cur;
   3487 	cur.next = t;
   3488 	next.prev = t;
   3489 	wrflags(flags);
   3490 	return t;
   3491 }
   3492 
   3493 enum {
   3494 	O_RDONLY = 0,
   3495 	O_WRONLY = 1,
   3496 	O_RDWR = 2,
   3497 	O_CREAT = 64,
   3498 	O_DIRECTORY = 0x1000,
   3499 }
   3500 
   3501 struct vpage {
   3502 	parent: *vpage;
   3503 	left: *vpage;
   3504 	right: *vpage;
   3505 	offset: int;
   3506 	page: *byte;
   3507 }
   3508 
   3509 struct vent {
   3510 	next: *vent;
   3511 	name: *byte;
   3512 	node: *vnode;
   3513 }
   3514 
   3515 struct vnode {
   3516 	refcount: int;
   3517 	ino: int;
   3518 	nlink: int;
   3519 	size: int;
   3520 	pages: *vpage;
   3521 	ents: *vent;
   3522 }
   3523 
   3524 struct vfile {
   3525 	refcount: int;
   3526 	mode: int;
   3527 	node: *vnode;
   3528 	offset: int;
   3529 }
   3530 
   3531 enum {
   3532 	S_IFMT = 0xf000,
   3533 	S_IFDIR = 0x4000,
   3534 	S_IFREG = 0x8000,
   3535 }
   3536 
   3537 func strlen(s: *byte): int {
   3538 	var i: int;
   3539 	i = 0;
   3540 	loop {
   3541 		if !s[i] {
   3542 			return i;
   3543 		}
   3544 		i = i + 1;
   3545 	}
   3546 }
   3547 
   3548 func strndup(s: *byte, n: int): *byte {
   3549 	var r: *byte;
   3550 	if n >= 4096 {
   3551 		kdie("str too large");
   3552 	}
   3553 	r = alloc();
   3554 	memcpy(r, s, n);
   3555 	r[n] = 0 as byte;
   3556 	return r;
   3557 }
   3558 
   3559 func strdup(s: *byte): *byte {
   3560 	return strndup(s, strlen(s));
   3561 }
   3562 
   3563 func mkvnode(): *vnode {
   3564 	var v: *vnode;
   3565 	var global: *global;
   3566 	global = g();
   3567 	v = alloc() as *vnode;
   3568 	v.refcount = 1;
   3569 	global.next_ino = global.next_ino + 1;
   3570 	v.nlink = 0;
   3571 	v.ino = global.next_ino;
   3572 	v.size = 0;
   3573 	v.pages = nil;
   3574 	v.ents = nil;
   3575 	return v;
   3576 }
   3577 
   3578 func mkfile(v: *vnode, mode: int): *vfile {
   3579 	var f: *vfile;
   3580 	if !v {
   3581 		v = mkvnode();
   3582 	}
   3583 	f = alloc() as *vfile;
   3584 	f.refcount = 1;
   3585 	f.mode = mode;
   3586 	f.offset = 0;
   3587 	f.node = v;
   3588 	return f;
   3589 }
   3590 
   3591 func mkroot(): *vfile {
   3592 	var f: *vfile;
   3593 	f = mkfile(nil, S_IFDIR);
   3594 	f.node.nlink = 1;
   3595 	vlink(f, ".", 1, f);
   3596 	return f;
   3597 }
   3598 
   3599 func efind(d: *vfile, name: *byte, nlen: int): *vent {
   3600 	var e: *vent;
   3601 	e = d.node.ents;
   3602 	loop {
   3603 		if !e {
   3604 			break;
   3605 		}
   3606 		if strlen(e.name) == nlen && !memcmp(e.name, name, nlen) {
   3607 			break;
   3608 		}
   3609 		e = e.next;
   3610 	}
   3611 	return e;
   3612 }
   3613 
   3614 func vlink(d: *vfile, name: *byte, nlen: int, f: *vfile) {
   3615 	var e: *vent;
   3616 	e = efind(d, name, nlen);
   3617 	if e {
   3618 		vrelease(e.node);
   3619 		e.node.nlink = e.node.nlink - 1;
   3620 		e.node = vnodedup(f.node);
   3621 	} else {
   3622 		e = alloc() as *vent;
   3623 		e.name = strndup(name, nlen);
   3624 		e.node = vnodedup(f.node);
   3625 		f.node.nlink = f.node.nlink + 1;
   3626 		e.next = d.node.ents;
   3627 		d.node.ents = e;
   3628 	}
   3629 	if nlen != 2 || memcmp(name, "..", 2) {
   3630 		vlink(f, "..", 2, d);
   3631 	}
   3632 }
   3633 
   3634 func vlookup(d: *vfile, name: *byte, nlen: int, flags: int, mode: int): *vfile {
   3635 	var f: *vfile;
   3636 	var e: *vent;
   3637 
   3638 	if !d {
   3639 		return nil;
   3640 	}
   3641 
   3642 	e = efind(d, name, nlen);
   3643 	if e {
   3644 		if flags & O_DIRECTORY {
   3645 			f = mkfile(e.node, S_IFDIR);
   3646 		} else {
   3647 			f = mkfile(e.node, S_IFREG);
   3648 		}
   3649 	} else {
   3650 		f = nil;
   3651 	}
   3652 
   3653 	if flags & O_CREAT && !f {
   3654 		if flags & O_DIRECTORY {
   3655 			f = mkfile(nil, S_IFDIR);
   3656 			vlink(f, ".", 1, f);
   3657 		} else {
   3658 			f = mkfile(nil, S_IFREG);
   3659 		}
   3660 		vlink(d, name, nlen, f);
   3661 	}
   3662 
   3663 	if !f {
   3664 		return f;
   3665 	}
   3666 
   3667 	if flags & O_DIRECTORY {
   3668 		if f.mode != S_IFDIR {
   3669 			vclose(f);
   3670 			return nil;
   3671 		}
   3672 	} else {
   3673 		if f.mode != S_IFREG {
   3674 			vclose(f);
   3675 			return nil;
   3676 		}
   3677 	}
   3678 
   3679 	return f;
   3680 }
   3681 
   3682 func vopen(name: *byte, flags: int, mode: int): *vfile {
   3683 	var d: *vfile;
   3684 	var f: *vfile;
   3685 	var i: int;
   3686 	var j: int;
   3687 	var n: int;
   3688 	var global: *global;
   3689 
   3690 	global = g();
   3691 
   3692 	if name[0] == '/' as byte {
   3693 		d = vdup(global.root);
   3694 	} else {
   3695 		d = vdup(global.curtask.cwd);
   3696 	}
   3697 
   3698 	i = 0;
   3699 	n = 0;
   3700 	loop {
   3701 		if !name[i] {
   3702 			break;
   3703 		}
   3704 		if name[i] != '/' as byte {
   3705 			n = i + 1;
   3706 		}
   3707 		i = i + 1;
   3708 	}
   3709 
   3710 	i = 0;
   3711 	j = 0;
   3712 	loop {
   3713 		if j == n {
   3714 			break;
   3715 		} else if name[j] == '/' as byte {
   3716 			if i == j {
   3717 				i = i + 1;
   3718 				j = j + 1;
   3719 				continue;
   3720 			}
   3721 			f = vlookup(d, &name[i], j - i, O_DIRECTORY, 0);
   3722 			vclose(d);
   3723 			d = f;
   3724 			i = j + 1;
   3725 			j = j + 1;
   3726 		} else {
   3727 			j = j + 1;
   3728 		}
   3729 	}
   3730 
   3731 	f = vlookup(d, &name[i], j - i, flags, mode);
   3732 	vclose(d);
   3733 
   3734 	return f;
   3735 }
   3736 
   3737 func vrelease_page(p: *vpage) {
   3738 	var q: *vpage;
   3739 
   3740 	loop {
   3741 		if !p {
   3742 			break;
   3743 		}
   3744 
   3745 		if p.left {
   3746 			p = p.left;
   3747 			continue;
   3748 		}
   3749 
   3750 		if p.right {
   3751 			p = p.right;
   3752 			continue;
   3753 		}
   3754 
   3755 		q = p.parent;
   3756 		if q {
   3757 			if q.left == p {
   3758 				q.left = nil;
   3759 			} else {
   3760 				q.right = nil;
   3761 			}
   3762 		}
   3763 
   3764 		p.parent = nil;
   3765 
   3766 		free(p.page);
   3767 		free(p as *byte);
   3768 
   3769 		p = q;
   3770 	}
   3771 }
   3772 
   3773 func vrelease(v: *vnode): int {
   3774 	var e: *vent;
   3775 	var n: *vent;
   3776 	v.refcount = v.refcount - 1;
   3777 	if v.refcount != 0 {
   3778 		return 0;
   3779 	}
   3780 	e = v.ents;
   3781 	loop {
   3782 		if !e {
   3783 			break;
   3784 		}
   3785 		n = e.next;
   3786 		vrelease(e.node);
   3787 		free(e.name);
   3788 		free(e as *byte);
   3789 		e = n;
   3790 	}
   3791 	vrelease_page(v.pages);
   3792 	free(v as *byte);
   3793 	return 0;
   3794 }
   3795 
   3796 func vclose(f: *vfile): int {
   3797 	var n: *vnode;
   3798 
   3799 	if !f {
   3800 		return 0;
   3801 	}
   3802 
   3803 	f.refcount = f.refcount - 1;
   3804 	if f.refcount != 0 {
   3805 		return 0;
   3806 	}
   3807 
   3808 	n = f.node;
   3809 
   3810 	free(f as *byte);
   3811 
   3812 	return vrelease(n);
   3813 }
   3814 
   3815 func vseek(f: *vfile, o: int, w: int): int {
   3816 	if w == 0 {
   3817 		f.offset = o;
   3818 	} else if w == 1 {
   3819 		f.offset = f.offset + o;
   3820 	} else if w == 2 {
   3821 		f.offset = f.node.size + o;
   3822 	} else {
   3823 		return -1;
   3824 	}
   3825 	if f.offset < 0 {
   3826 		f.offset = 0;
   3827 	}
   3828 	return f.offset;
   3829 }
   3830 
   3831 func vwrite_page(v: *vnode, o: int, b: *byte, n: int): int {
   3832 	var key: int;
   3833 	var p: *vpage;
   3834 	var q: *vpage;
   3835 
   3836 	if o + n > v.size {
   3837 		v.size = o + n;
   3838 	}
   3839 
   3840 	key = o & -4096;
   3841 	o = o & 4095;
   3842 
   3843 	if n > 4096 - o {
   3844 		n = 4096 - o;
   3845 	}
   3846 
   3847 	p = v.pages;
   3848 	if !p {
   3849 		q = alloc() as *vpage;
   3850 		q.parent = nil;
   3851 		q.left = nil;
   3852 		q.right = nil;
   3853 		q.offset = key;
   3854 		q.page = alloc();
   3855 		bzero(q.page, 4096);
   3856 		v.pages = q;
   3857 		p = q;
   3858 	}
   3859 
   3860 	loop {
   3861 		if key < p.offset {
   3862 			if !p.left {
   3863 				q = alloc() as *vpage;
   3864 				q.parent = p;
   3865 				q.left = nil;
   3866 				q.right = nil;
   3867 				q.offset = key;
   3868 				q.page = alloc();
   3869 				bzero(q.page, 4096);
   3870 				p.left = q;
   3871 				p = q;
   3872 			} else {
   3873 				p = p.left;
   3874 			}
   3875 		} else if key > p.offset {
   3876 			if ! p.right {
   3877 				q = alloc() as *vpage;
   3878 				q.parent = p;
   3879 				q.left = nil;
   3880 				q.right = nil;
   3881 				q.offset = key;
   3882 				q.page = alloc();
   3883 				bzero(q.page, 4096);
   3884 				p.right = q;
   3885 				p = q;
   3886 			} else {
   3887 				p = p.right;
   3888 			}
   3889 		} else {
   3890 			break;
   3891 		}
   3892 	}
   3893 
   3894 	memcpy(&p.page[o], b, n);
   3895 	return n;
   3896 }
   3897 
   3898 func vread_page(v: *vnode, o: int, b: *byte, n: int): int {
   3899 	var key: int;
   3900 	var p: *vpage;
   3901 
   3902 	if o > v.size {
   3903 		return 0;
   3904 	}
   3905 
   3906 	if v.size - o < n {
   3907 		n = v.size - o;
   3908 	}
   3909 
   3910 	key = o & -4096;
   3911 	o = o & 4095;
   3912 
   3913 	if n > 4096 - o {
   3914 		n = 4096 - o;
   3915 	}
   3916 
   3917 	p = v.pages;
   3918 	if !p {
   3919 		return 0;
   3920 	}
   3921 
   3922 	loop {
   3923 		if !p {
   3924 			break;
   3925 		} else if key < p.offset {
   3926 			p = p.left;
   3927 		} else if key > p.offset {
   3928 			p = p.right;
   3929 		} else {
   3930 			break;
   3931 		}
   3932 	}
   3933 
   3934 	if !p {
   3935 		bzero(b, n);
   3936 	} else {
   3937 		memcpy(b, &p.page[o], n);
   3938 	}
   3939 
   3940 	return n;
   3941 }
   3942 
   3943 func vwrite(f: *vfile, b: *byte, n: int): int {
   3944 	var o: int;
   3945 	var m: int;
   3946 	var len: int;
   3947 	var ret: int;
   3948 
   3949 	o = f.offset;
   3950 	m = 0;
   3951 	loop {
   3952 		if n == 0 {
   3953 			break;
   3954 		}
   3955 
   3956 		len = 4096 - (o & 4095);
   3957 		if len > n {
   3958 			len = n;
   3959 		}
   3960 
   3961 		len = vwrite_page(f.node, o, b, len);
   3962 		if len == 0 {
   3963 			break;
   3964 		}
   3965 
   3966 		o = o + len;
   3967 		n = n - len;
   3968 		m = m + len;
   3969 		b = &b[len];
   3970 	}
   3971 
   3972 	f.offset = o;
   3973 
   3974 	if m == 0 {
   3975 		return -1;
   3976 	}
   3977 
   3978 	return m;
   3979 }
   3980 
   3981 func vread(f: *vfile, b: *byte, n: int): int {
   3982 	var o: int;
   3983 	var m: int;
   3984 	var len: int;
   3985 	var ret: int;
   3986 
   3987 	o = f.offset;
   3988 	m = 0;
   3989 	loop {
   3990 		if n == 0 {
   3991 			break;
   3992 		}
   3993 
   3994 		len = 4096 - (o & 4095);
   3995 		if len > n {
   3996 			len = n;
   3997 		}
   3998 
   3999 		len = vread_page(f.node, o, b, len);
   4000 		if len == 0 {
   4001 			break;
   4002 		}
   4003 
   4004 		o = o + len;
   4005 		n = n - len;
   4006 		m = m + len;
   4007 		b = &b[len];
   4008 	}
   4009 
   4010 	f.offset = o;
   4011 
   4012 	return m;
   4013 }
   4014 
   4015 func vdup(f: *vfile): *vfile {
   4016 	f.refcount = f.refcount + 1;
   4017 	return f;
   4018 }
   4019 
   4020 func vnodedup(v: *vnode): *vnode {
   4021 	v.refcount = v.refcount + 1;
   4022 	return v;
   4023 }
   4024 
   4025 func vmkdir(name: *byte): *vfile {
   4026 	return vopen(name, O_DIRECTORY | O_CREAT, 0);
   4027 }
   4028 
   4029 func _ssr(r: *regs) {
   4030 	if r.rax == 0 {
   4031 		kputs("read\n");
   4032 		r.rax = -1;
   4033 	} else if r.rax == 1 {
   4034 		xxd(r.rsi as *byte, r.rdx);
   4035 		r.rax = r.rdx;
   4036 	} else if r.rax == 2 {
   4037 		kputs("open\n");
   4038 		r.rax = -1;
   4039 	} else if r.rax == 3 {
   4040 		kputs("close\n");
   4041 		r.rax = -1;
   4042 	} else if r.rax == 5 {
   4043 		kputs("fstat\n");
   4044 		r.rax = -1;
   4045 	} else if r.rax == 9 {
   4046 		kputs("mmap\n");
   4047 		r.rax = -1;
   4048 	} else if r.rax == 22 {
   4049 		kputs("pipe\n");
   4050 		r.rax = -1;
   4051 	} else if r.rax == 33 {
   4052 		kputs("dup2\n");
   4053 		r.rax = -1;
   4054 	} else if r.rax == 41 {
   4055 		kputs("socket\n");
   4056 		r.rax = -1;
   4057 	} else if r.rax == 43 {
   4058 		kputs("accept\n");
   4059 		r.rax = -1;
   4060 	} else if r.rax == 49 {
   4061 		kputs("bind\n");
   4062 		r.rax = -1;
   4063 	} else if r.rax == 50 {
   4064 		kputs("listen\n");
   4065 		r.rax = -1;
   4066 	} else if r.rax == 57 {
   4067 		kputs("fork\n");
   4068 		r.rax = -1;
   4069 	} else if r.rax == 59 {
   4070 		kputs("exec\n");
   4071 		r.rax = -1;
   4072 	} else if r.rax == 60 {
   4073 		kputs("exit(");
   4074 		kputd(r.rdi);
   4075 		kputs(")\n");
   4076 		task_exit();
   4077 	} else if r.rax == 61 {
   4078 		kputs("wait\n");
   4079 		r.rax = -1;
   4080 	} else if r.rax == 82 {
   4081 		kputs("rename\n");
   4082 		r.rax = -1;
   4083 	} else if r.rax == 87 {
   4084 		kputs("mkdir\n");
   4085 		r.rax = -1;
   4086 	} else if r.rax == 87 {
   4087 		kputs("unlink\n");
   4088 		r.rax = -1;
   4089 	} else if r.rax == 217 {
   4090 		kputs("getdirents\n");
   4091 		r.rax = -1;
   4092 	} else {
   4093 		r.rax = -1;
   4094 	}
   4095 }
   4096 
   4097 func initramfs(len: *int): *byte {
   4098 	return _include("initramfs", len);
   4099 }
   4100 
   4101 func parse_hex32(i: int, r: *byte, n: int, x: *int): int {
   4102 	var j: int;
   4103 	var z: int;
   4104 
   4105 	if i + 8 > n {
   4106 		return -1;
   4107 	}
   4108 
   4109 	z = 0;
   4110 	j = 32;
   4111 	loop {
   4112 		if j == 0 {
   4113 			break;
   4114 		}
   4115 
   4116 		j = j - 4;
   4117 
   4118 		if r[i] >= '0' as byte && r[i] <= '9' as byte {
   4119 			z = z | ((r[i] as int - '0') << j);
   4120 		} else if r[i] >= 'a' as byte && r[i] <= 'f' as byte {
   4121 			z = z | ((r[i] as int - 'a' + 10) << j);
   4122 		} else if r[i] >= 'A' as byte && r[i] <= 'F' as byte {
   4123 			z = z | ((r[i] as int - 'A' + 10) << j);
   4124 		} else {
   4125 			return -1;
   4126 		}
   4127 
   4128 		i = i + 1;
   4129 	}
   4130 
   4131 	*x = z;
   4132 	return i;
   4133 }
   4134 
   4135 func parse_initramfs_file(i: int, r: *byte, n: int): int {
   4136 	var ino: int;
   4137 	var mode: int;
   4138 	var uid: int;
   4139 	var gid: int;
   4140 	var nlink: int;
   4141 	var mtime: int;
   4142 	var size: int;
   4143 	var dev_major: int;
   4144 	var dev_minor: int;
   4145 	var rdev_major: int;
   4146 	var rdev_minor: int;
   4147 	var namelen: int;
   4148 	var reserved: int;
   4149 	var name: *byte;
   4150 	var data: *byte;
   4151 
   4152 	if memcmp(&r[i], "070701", 6) != 0 {
   4153 		return -1;
   4154 	}
   4155 
   4156 	i = i + 6;
   4157 
   4158 	i = parse_hex32(i, r, n, &ino);
   4159 	i = parse_hex32(i, r, n, &mode);
   4160 	i = parse_hex32(i, r, n, &uid);
   4161 	i = parse_hex32(i, r, n, &gid);
   4162 	i = parse_hex32(i, r, n, &nlink);
   4163 	i = parse_hex32(i, r, n, &mtime);
   4164 	i = parse_hex32(i, r, n, &size);
   4165 	i = parse_hex32(i, r, n, &dev_major);
   4166 	i = parse_hex32(i, r, n, &dev_minor);
   4167 	i = parse_hex32(i, r, n, &rdev_major);
   4168 	i = parse_hex32(i, r, n, &rdev_minor);
   4169 	i = parse_hex32(i, r, n, &namelen);
   4170 	i = parse_hex32(i, r, n, &reserved);
   4171 
   4172 	if i < 0 {
   4173 		return -1;
   4174 	}
   4175 
   4176 	name = &r[i];
   4177 	i = i + namelen;
   4178 
   4179 	if namelen < 1 || i > n {
   4180 		return -1;
   4181 	}
   4182 
   4183 	i = (i + 3) & -4;
   4184 	if i > n {
   4185 		return -1;
   4186 	}
   4187 
   4188 	if name[namelen - 1] {
   4189 		return -1;
   4190 	}
   4191 
   4192 	data = &r[i];
   4193 	i = i + size;
   4194 
   4195 	i = (i + 3) & -4;
   4196 	if i > n {
   4197 		return -1;
   4198 	}
   4199 
   4200 	if namelen == 11 && !memcmp(name, "TRAILER!!!", 11) {
   4201 		return i;
   4202 	}
   4203 
   4204 	initramfs_create(name, data, size, mode);
   4205 
   4206 	return i;
   4207 }
   4208 
   4209 func parse_initramfs() {
   4210 	var r: *byte;
   4211 	var len: int;
   4212 	var i: int;
   4213 	var global: *global;
   4214 
   4215 	global = g();
   4216 	global.root = mkroot();
   4217 	global.curtask.cwd = vdup(global.root);
   4218 
   4219 	r = initramfs(&len);
   4220 
   4221 	i = 0;
   4222 	loop {
   4223 		if i == len || i < 0 {
   4224 			break;
   4225 		}
   4226 		i = parse_initramfs_file(i, r, len);
   4227 	}
   4228 }
   4229 
   4230 func initramfs_create(name: *byte, data: *byte, size: int, mode: int) {
   4231 	var type: int;
   4232 	var n: int;
   4233 	var ret: int;
   4234 	var f: *vfile;
   4235 	type = mode & S_IFMT;
   4236 	if type == S_IFDIR {
   4237 		// directory
   4238 		vclose(vmkdir(name));
   4239 	} else if type == S_IFREG {
   4240 		// regular file
   4241 		f = vopen(name, O_CREAT, mode & 0xfff);
   4242 		if f {
   4243 			n = 0;
   4244 			loop {
   4245 				if n == size {
   4246 					break;
   4247 				}
   4248 				ret = vwrite(f, &data[n], size - n);
   4249 				if ret < 0 {
   4250 					kdie("write failed");
   4251 				}
   4252 				n = n + ret;
   4253 			}
   4254 			vclose(f);
   4255 		} else {
   4256 			kdie("create failed");
   4257 		}
   4258 	}
   4259 }
   4260 
   4261 func userswitch(entry: int, stack: int) {
   4262 	var r: regs;
   4263 	var discard: regs;
   4264 	bzero((&r) as *byte, sizeof(r));
   4265 	r.rflags = 0x200;
   4266 	r.rip = entry;
   4267 	r.cs = 40 | 3;
   4268 	r.rsp = stack;
   4269 	r.ss = 32 | 3;
   4270 	invlpt();
   4271 	taskswitch(&discard, &r);
   4272 }
   4273 
   4274 func map_user(vaddr: int): *byte {
   4275 	var global: *global;
   4276 	var task: *task;
   4277 	var pt: *int;
   4278 	var i: int;
   4279 
   4280 	if (vaddr >> 47) != 0 || (vaddr & 4095) != 0 {
   4281 		return nil;
   4282 	}
   4283 
   4284 	global = g();
   4285 	task = global.curtask;
   4286 
   4287 	pt = ptov(task.pt) as *int;
   4288 
   4289 	i = (vaddr >> 39) & 255;
   4290 	if !pt[i] {
   4291 		pt[i] = alloc_page() | 7;
   4292 		bzero(ptov(pt[i] & -4096), 4096);
   4293 	}
   4294 	pt = ptov(pt[i] & -4096) as *int;
   4295 
   4296 	i = (vaddr >> 30) & 511;
   4297 	if !pt[i] {
   4298 		pt[i] = alloc_page() | 7;
   4299 		bzero(ptov(pt[i] & -4096), 4096);
   4300 	}
   4301 	pt = ptov(pt[i] & -4096) as *int;
   4302 
   4303 	i = (vaddr >> 21) & 511;
   4304 	if !pt[i] {
   4305 		pt[i] = alloc_page() | 7;
   4306 		bzero(ptov(pt[i] & -4096), 4096);
   4307 	}
   4308 	pt = ptov(pt[i] & -4096) as *int;
   4309 
   4310 	i = (vaddr >> 12) & 511;
   4311 	if !pt[i] {
   4312 		pt[i] = alloc_page() | 7;
   4313 		bzero(ptov(pt[i] & -4096), 4096);
   4314 		return ptov(pt[i] & -4096);
   4315 	}
   4316 
   4317 	return nil;
   4318 }
   4319 
   4320 func vload(f: *vfile, offset: int, vaddr: int, filesz: int, memsz: int): int {
   4321 	var t: *task;
   4322 	var i: int;
   4323 	var o: int;
   4324 	var sz: int;
   4325 	var m: *byte;
   4326 
   4327 	if filesz != 0 && (offset & 4095) != (vaddr & 4095) {
   4328 		return -1;
   4329 	}
   4330 
   4331 	if filesz > memsz {
   4332 		return -1;
   4333 	}
   4334 
   4335 	if offset < 0 || vaddr < 0 {
   4336 		return -1;
   4337 	}
   4338 
   4339 	if vaddr < 4096 {
   4340 		return -1;
   4341 	}
   4342 
   4343 	if filesz > 0 {
   4344 		if vseek(f, offset, 0) != offset {
   4345 			return -1;
   4346 		}
   4347 	}
   4348 
   4349 	i = 0;
   4350 	loop {
   4351 		if i >= memsz {
   4352 			break;
   4353 		}
   4354 		o = (vaddr + i) & 4065;
   4355 		sz = 4096 - o;
   4356 		m = map_user((vaddr + i) & -4096);
   4357 		if !m {
   4358 			return -1;
   4359 		}
   4360 		if i < filesz {
   4361 			if sz > filesz - i {
   4362 				if vread(f, &m[o], filesz - i) != filesz - i {
   4363 					return -1;
   4364 				}
   4365 			} else {
   4366 				if vread(f, &m[o], sz) != sz {
   4367 					return -1;
   4368 				}
   4369 			}
   4370 		}
   4371 		i = i + sz;
   4372 	}
   4373 
   4374 	return 0;
   4375 }
   4376 
   4377 func map_stack(argc: int, argv: **byte, envc: int, envv: **byte): int {
   4378 	var m: *int;
   4379 	var i: int;
   4380 	var sp: int;
   4381 	var n: int;
   4382 	var len: int;
   4383 
   4384 	sp = 0x7fffe000;
   4385 	m = map_user(sp) as *int;
   4386 
   4387 	if !m {
   4388 		return 0;
   4389 	}
   4390 
   4391 	m[0] = argc;
   4392 	m[argc] = 0;
   4393 	m[argc + envc + 1] = 0;
   4394 
   4395 	n = argc * 8 + envc * 8 + 24;
   4396 
   4397 	// copy args
   4398 	i = 0;
   4399 	loop {
   4400 		if i == argc {
   4401 			break;
   4402 		}
   4403 
   4404 		len = strlen(argv[i]);
   4405 		if len >= 4096 - n {
   4406 			return 0;
   4407 		}
   4408 
   4409 		memcpy(&(m as *byte)[n], argv[i], len + 1);
   4410 
   4411 		m[i + 1] = sp + n;
   4412 
   4413 		i = i + 1;
   4414 		n = n + len + 1;
   4415 	}
   4416 
   4417 	// copy env
   4418 	i = 0;
   4419 	loop {
   4420 		if i == envc {
   4421 			break;
   4422 		}
   4423 
   4424 		len = strlen(envv[i]);
   4425 		if len >= 4096 - n {
   4426 			return 0;
   4427 		}
   4428 
   4429 		memcpy(&(m as *byte)[n], envv[i], len + 1);
   4430 
   4431 		m[argc + i + 1] = sp + n;
   4432 
   4433 		i = i + 1;
   4434 		n = n + len + 1;
   4435 	}
   4436 
   4437 	// Allocate a user stack
   4438 	i = 1;
   4439 	loop {
   4440 		if i == 16 {
   4441 			break;
   4442 		}
   4443 		if !map_user(0x7fffe000 - 4096 * i) {
   4444 			return 0;
   4445 		}
   4446 		i = i + 1;
   4447 	}
   4448 
   4449 	return sp;
   4450 }
   4451 
   4452 func vexec(prog: *byte, argv: **byte, envp: **byte): int {
   4453 	var f: *vfile;
   4454 	var head: *byte;
   4455 	var args: **byte;
   4456 	var envs: **byte;
   4457 	var nargs: int;
   4458 	var nenv: int;
   4459 	var n: int;
   4460 	var i: int;
   4461 	var entry: int;
   4462 	var phoff: int;
   4463 	var phnum: int;
   4464 	var size: int;
   4465 	var p_type: int;
   4466 	var p_offset: int;
   4467 	var p_vaddr: int;
   4468 	var p_filesz: int;
   4469 	var p_memsz: int;
   4470 	var pt: int;
   4471 	var global: *global;
   4472 	var t: *task;
   4473 	var stack: int;
   4474 
   4475 	global = g();
   4476 	t = global.curtask;
   4477 
   4478 	pt = t.pt;
   4479 	t.pt = alloc_page();
   4480 	bzero(ptov(t.pt), 4096);
   4481 
   4482 	head = alloc();
   4483 	args = alloc() as **byte;
   4484 	envs = alloc() as **byte;
   4485 	nargs = 0;
   4486 	nenv = 0;
   4487 	f = nil;
   4488 
   4489 	// Copy args
   4490 	if argv {
   4491 		loop {
   4492 			if nargs == 512 {
   4493 				goto fail;
   4494 			}
   4495 			if !argv[nargs] {
   4496 				break;
   4497 			}
   4498 			args[nargs] = strdup(argv[nargs]);
   4499 			nargs = nargs + 1;
   4500 		}
   4501 	}
   4502 
   4503 	// Copy environment
   4504 	if envp {
   4505 		loop {
   4506 			if nenv == 512 {
   4507 				goto fail;
   4508 			}
   4509 			if !envp[nenv] {
   4510 				break;
   4511 			}
   4512 			envs[nenv] = strdup(envp[nenv]);
   4513 			nenv = nenv + 1;
   4514 		}
   4515 	}
   4516 
   4517 	// Find interpreter
   4518 	loop {
   4519 		f = vopen(prog, O_RDONLY, 0);
   4520 		if !f {
   4521 			goto fail;
   4522 		}
   4523 
   4524 		n = vread(f, head, 4096);
   4525 		if n >= 2 && head[0] == '#' as byte && head[1] == '!' as byte {
   4526 			nargs = nargs + 1;
   4527 			i = nargs;
   4528 			loop {
   4529 				if i == 0 {
   4530 					break;
   4531 				}
   4532 				i = i - 1;
   4533 				args[i] = args[i - 1];
   4534 			}
   4535 
   4536 			i = 2;
   4537 			loop {
   4538 				if i == n {
   4539 					goto fail;
   4540 				}
   4541 				if head[i] == '\n' as byte {
   4542 					break;
   4543 				}
   4544 				i = i + 1;
   4545 			}
   4546 
   4547 			args[0] = strndup(&head[2], i - 2);
   4548 			if nargs > 1 {
   4549 				free(args[1]);
   4550 			} else {
   4551 				nargs = 2;
   4552 			}
   4553 			args[1] = strdup(prog);
   4554 			prog = args[0];
   4555 			vclose(f);
   4556 			f = nil;
   4557 			continue;
   4558 		}
   4559 
   4560 		break;
   4561 	}
   4562 
   4563 	size = f.node.size;
   4564 
   4565 	// Load elf
   4566 	if n < 0x40 {
   4567 		goto fail;
   4568 	}
   4569 
   4570 	// magic
   4571 	if !(head[0] as int == 0x7f && head[1] as int == 0x45 && head[2] as int == 0x4c && head[3] as int == 0x46) {
   4572 		goto fail;
   4573 	}
   4574 
   4575 	// 64 bit
   4576 	if head[4] as int != 2 {
   4577 		goto fail;
   4578 	}
   4579 
   4580 	// little endian
   4581 	if head[5] as int != 1 {
   4582 		goto fail;
   4583 	}
   4584 
   4585 	// version
   4586 	if head[6] as int != 1 {
   4587 		goto fail;
   4588 	}
   4589 
   4590 	// executable
   4591 	if head[17] as int != 0 || head[16] as int != 2 {
   4592 		goto fail;
   4593 	}
   4594 
   4595 	// machine
   4596 	if head[19] as int != 0 || head[18] as int != 0x3e {
   4597 		goto fail;
   4598 	}
   4599 
   4600 	// version
   4601 	if !(head[23] as int == 0 && head[22] as int == 0 && head[21] as int == 0 && head[20] as int == 1) {
   4602 		goto fail;
   4603 	}
   4604 
   4605 	// ehsize
   4606 	if !(head[0x35] as int == 0 && head[0x34] as int == 0x40) {
   4607 		goto fail;
   4608 	}
   4609 
   4610 	// phentsize
   4611 	if !(head[0x37] as int == 0 && head[0x36] as int == 0x38) {
   4612 		goto fail;
   4613 	}
   4614 
   4615 	// entry point
   4616 	entry = head[24] as int
   4617 		| (head[25] as int << 8)
   4618 		| (head[26] as int << 16)
   4619 		| (head[27] as int << 24)
   4620 		| (head[28] as int << 32)
   4621 		| (head[29] as int << 40)
   4622 		| (head[30] as int << 48)
   4623 		| (head[31] as int << 56);
   4624 	if entry < 0 {
   4625 		goto fail;
   4626 	}
   4627 
   4628 	phoff = head[32] as int
   4629 		| (head[33] as int << 8)
   4630 		| (head[34] as int << 16)
   4631 		| (head[35] as int << 24)
   4632 		| (head[36] as int << 32)
   4633 		| (head[37] as int << 40)
   4634 		| (head[38] as int << 48)
   4635 		| (head[39] as int << 56);
   4636 
   4637 	phnum = head[0x38] as int
   4638 		| (head[0x39] as int << 8);
   4639 	if phnum > 64 {
   4640 		goto fail;
   4641 	}
   4642 
   4643 	if phoff > size || 56 * phnum > size - phoff {
   4644 		goto fail;
   4645 	}
   4646 
   4647 	if vseek(f, phoff, 0) != phoff {
   4648 		goto fail;
   4649 	}
   4650 
   4651 	n = vread(f, head, 56 * phnum);
   4652 	if n != 56 * phnum {
   4653 		goto fail;
   4654 	}
   4655 
   4656 	i = 0;
   4657 	loop {
   4658 		if i == phnum {
   4659 			break;
   4660 		}
   4661 
   4662 		p_type = head[i * 56 + 0] as int
   4663 			| (head[i * 56 + 1] as int << 8)
   4664 			| (head[i * 56 + 2] as int << 16)
   4665 			| (head[i * 56 + 3] as int << 24);
   4666 		p_offset = head[i * 56 + 8] as int
   4667 			| (head[i * 56 + 9] as int << 8)
   4668 			| (head[i * 56 + 10] as int << 16)
   4669 			| (head[i * 56 + 11] as int << 24)
   4670 			| (head[i * 56 + 12] as int << 32)
   4671 			| (head[i * 56 + 13] as int << 40)
   4672 			| (head[i * 56 + 14] as int << 48)
   4673 			| (head[i * 56 + 15] as int << 56);
   4674 		p_vaddr = head[i * 56 + 16] as int
   4675 			| (head[i * 56 + 17] as int << 8)
   4676 			| (head[i * 56 + 18] as int << 16)
   4677 			| (head[i * 56 + 19] as int << 24)
   4678 			| (head[i * 56 + 20] as int << 32)
   4679 			| (head[i * 56 + 21] as int << 40)
   4680 			| (head[i * 56 + 22] as int << 48)
   4681 			| (head[i * 56 + 23] as int << 56);
   4682 		p_filesz = head[i * 56 + 32] as int
   4683 			| (head[i * 56 + 33] as int << 8)
   4684 			| (head[i * 56 + 34] as int << 16)
   4685 			| (head[i * 56 + 35] as int << 24)
   4686 			| (head[i * 56 + 36] as int << 32)
   4687 			| (head[i * 56 + 37] as int << 40)
   4688 			| (head[i * 56 + 38] as int << 48)
   4689 			| (head[i * 56 + 39] as int << 56);
   4690 		p_memsz = head[i * 56 + 40] as int
   4691 			| (head[i * 56 + 41] as int << 8)
   4692 			| (head[i * 56 + 42] as int << 16)
   4693 			| (head[i * 56 + 43] as int << 24)
   4694 			| (head[i * 56 + 44] as int << 32)
   4695 			| (head[i * 56 + 45] as int << 40)
   4696 			| (head[i * 56 + 46] as int << 48)
   4697 			| (head[i * 56 + 47] as int << 56);
   4698 
   4699 		if p_type == 1 {
   4700 			if vload(f, p_offset, p_vaddr, p_filesz, p_memsz) != 0 {
   4701 				goto fail;
   4702 			}
   4703 		}
   4704 
   4705 		i = i + 1;
   4706 	}
   4707 
   4708 	// allocate a stack
   4709 	stack = map_stack(nargs, args, nenv, envs);
   4710 	if !stack {
   4711 		goto fail;
   4712 	}
   4713 
   4714 	vclose(f);
   4715 	i = 0;
   4716 	loop {
   4717 		if i == nargs {
   4718 			break;
   4719 		}
   4720 		if args[i] {
   4721 			free(args[i]);
   4722 		}
   4723 		i = i + 1;
   4724 	}
   4725 	i = 0;
   4726 	loop {
   4727 		if i == nenv {
   4728 			break;
   4729 		}
   4730 		if envs[i] {
   4731 			free(envs[i]);
   4732 		}
   4733 		i = i + 1;
   4734 	}
   4735 	free(head);
   4736 	free(args as *byte);
   4737 	free(envs as *byte);
   4738 	freept(pt);
   4739 	userswitch(entry, stack);
   4740 	kdie("unreachable");
   4741 
   4742 fail:
   4743 	if f {
   4744 		vclose(f);
   4745 	}
   4746 	i = 0;
   4747 	loop {
   4748 		if i == nargs {
   4749 			break;
   4750 		}
   4751 		if args[i] {
   4752 			free(args[i]);
   4753 		}
   4754 		i = i + 1;
   4755 	}
   4756 	i = 0;
   4757 	loop {
   4758 		if i == nenv {
   4759 			break;
   4760 		}
   4761 		if envs[i] {
   4762 			free(envs[i]);
   4763 		}
   4764 		i = i + 1;
   4765 	}
   4766 	free(head);
   4767 	free(args as *byte);
   4768 	free(envs as *byte);
   4769 	freept(t.pt);
   4770 	t.pt = pt;
   4771 	return -1;
   4772 }
   4773 
   4774 func task_init(t: *task) {
   4775 	// open("/dev/null") => 0
   4776 	// open("/dev/tty") => 1
   4777 	// dup(1) => 2
   4778 	//if vexec("/init", nil, nil) != 0 {
   4779 	//	kdie("failed to exec init");
   4780 	//}
   4781 	loop {
   4782 		yield();
   4783 	}
   4784 }
   4785 
   4786 func _kstart(mb: int) {
   4787 	var global: global;
   4788 	var task: task;
   4789 	var brk: int;
   4790 	var tss: *int;
   4791 	var tss_size: int;
   4792 	var idt: *int;
   4793 	var idt_size: int;
   4794 	var gdt: *int;
   4795 	var gdt_size: int;
   4796 	var rsdt: int;
   4797 	var mcfg: int;
   4798 	var pcip: int;
   4799 	var pci: *byte;
   4800 	var flag: int;
   4801 	var mbinfo: *byte;
   4802 	var mmap: *int;
   4803 	var mmap_len: int;
   4804 	var mmap_count: int;
   4805 	var fr: *free_range;
   4806 
   4807 	bzero((&task) as *byte, sizeof(task));
   4808 	task.next = &task;
   4809 	task.prev = &task;
   4810 	task.name = "_kstart";
   4811 	task.pt = rdcr3();
   4812 
   4813 	bzero((&global) as *byte, sizeof(global));
   4814 	global.ptr = &global;
   4815 	global.ip = (192 << 24) + (168 << 16) + (1 << 8) + 148;
   4816 	global.ip_gw = (192 << 24) + (168 << 16) + (1 << 8) + 1;
   4817 	global.ip_mask = 20;
   4818 	global.curtask = &task;
   4819 	wrmsr(0xc0000101, global.ptr as int);
   4820 
   4821 	global.mmio = -(1 << 31);
   4822 
   4823 	brk = ptov(1024 * 1024 * 3) as int;
   4824 
   4825 	vinit(&global.vga, ptov(0xB8000), brk as *byte);
   4826 	brk = brk + 4096;
   4827 
   4828 	vclear(&global.vga);
   4829 	kputs("Starting up\n");
   4830 
   4831 	global.fr = nil;
   4832 	global.fp = nil;
   4833 	global.kpt = rdcr3();
   4834 
   4835 	mbinfo = ptov(mb);
   4836 	mmap = ptov(_r32(&mbinfo[48]) + 4) as *int;
   4837 	mmap_len = _r32(&mbinfo[44]);
   4838 	mmap_count = mmap_len / 24;
   4839 
   4840 	insert_sort(mmap as *void, mmap_count, 24, mmap_cmp);
   4841 
   4842 	var i: int;
   4843 	var mmap_start: int;
   4844 	var mmap_end: int;
   4845 	i = 0;
   4846 	loop {
   4847 		if i == mmap_count {
   4848 			break;
   4849 		}
   4850 
   4851 		mmap_start = mmap[i * 3];
   4852 		mmap_end = mmap_start + mmap[i * 3 + 1];
   4853 
   4854 		kputh(mmap_start);
   4855 		kputc('-');
   4856 		kputh(mmap_end);
   4857 		kputc(' ');
   4858 		kputh8(mmap[i * 3 + 2] & 15);
   4859 		kputc('\n');
   4860 
   4861 		if i + 1 < mmap_count {
   4862 			if mmap_end > mmap[i * 3 + 3] {
   4863 				kdie("OVERLAP");
   4864 				loop {
   4865 					cli();
   4866 					hlt();
   4867 				}
   4868 			}
   4869 		}
   4870 
   4871 		mmap_start = (mmap_start + 4095) & -4096;
   4872 		mmap_end = mmap_end & -4096;
   4873 
   4874 		if mmap_start < 0x400000 {
   4875 			mmap_start = 0x400000;
   4876 		}
   4877 
   4878 		if mmap_start < mmap_end && _r32((&mmap[i * 3 + 2]) as *byte) == 1 {
   4879 			fr = brk as *free_range;
   4880 			brk = brk + sizeof(*fr);
   4881 			fr.next = global.fr;
   4882 			fr.start = mmap_start;
   4883 			fr.end = mmap_end;
   4884 			global.fr = fr;
   4885 		}
   4886 
   4887 		i = i + 1;
   4888 	}
   4889 
   4890 	// Directly map all memory to just above the architectural hole
   4891 	direct_map(&brk);
   4892 
   4893 	// Zero tss and add interrupt stacks
   4894 	tss = brk as *int;
   4895 	tss_size = 104;
   4896 	brk = brk + tss_size;
   4897 	bzero(tss as *byte, tss_size);
   4898 
   4899 	// Fill idt with interrupt gates
   4900 	idt = brk as *int;
   4901 	idt_size = 4096;
   4902 	brk = brk + idt_size;
   4903 	fill_idt(idt);
   4904 
   4905 	gdt = brk as *int;
   4906 	gdt_size = 8 * 9;
   4907 
   4908 	// Null segment
   4909 	gdt[0] = 0;
   4910 	// Kernel code segment
   4911 	gdt[1] = 0x00209800 << 32;
   4912 	// Kernel data segment
   4913 	gdt[2] = 0x00009200 << 32;
   4914 	// User code segment
   4915 	gdt[3] = 0x0020fa00 << 32;
   4916 	// User data segment
   4917 	gdt[4] = 0x0000f200 << 32;
   4918 	// User code segment
   4919 	gdt[5] = 0x0020fa00 << 32;
   4920 	// User data segment
   4921 	gdt[6] = 0x0000f200 << 32;
   4922 	// Task segment
   4923 	gdt_tss(&gdt[7], tss as int, tss_size, 0x89, 0);
   4924 
   4925 	// Load gdt idt tss and segments
   4926 	lgdt(gdt, gdt_size);
   4927 	lseg(8, 16);
   4928 	wrmsr(0xc0000101, global.ptr as int);
   4929 	lldt(0);
   4930 	ltr(7 * 8);
   4931 	lidt(idt, idt_size);
   4932 
   4933 	// STAR
   4934 	wrmsr(0xc0000081, ((24 + 3) << 48) | (8 << 32));
   4935 	// LSTAR
   4936 	wrmsr(0xc0000082, (_ssr0) as int);
   4937 	// FMASK
   4938 	wrmsr(0xc0000084, -1);
   4939 	// EFER
   4940 	wrmsr(0xc0000080, rdmsr(0xc0000080) | 1);
   4941 
   4942 	// interrupt stack
   4943 	brk = (brk + 4095) & -4096;
   4944 	brk = brk + 64 * 1024;
   4945 	((tss as int + 0x24) as *int)[0] = brk;
   4946 	((tss as int + 0x04) as *int)[0] = brk;
   4947 
   4948 	// nmi stack
   4949 	brk = (brk + 4095) & -4096;
   4950 	brk = brk + 64 * 1024;
   4951 	((tss as int + 0x2c) as *int)[0] = brk;
   4952 
   4953 	// mask pic
   4954 	outb(IO_PIC1 + 1, 0xff);
   4955 	outb(IO_PIC2 + 1, 0xff);
   4956 
   4957 	// initialize pic
   4958 	outb(IO_PIC1, 0x11);
   4959 	outb(IO_PIC2, 0x11);
   4960 
   4961 	// pic offset
   4962 	outb(IO_PIC1 + 1, 32);
   4963 	outb(IO_PIC2 + 1, 40);
   4964 
   4965 	// pic cascade
   4966 	outb(IO_PIC1 + 1, 4);
   4967 	outb(IO_PIC2 + 1, 2);
   4968 
   4969 	// pic 8086 mode
   4970 	outb(IO_PIC1 + 1, 32);
   4971 	outb(IO_PIC2 + 1, 40);
   4972 
   4973 	// 1000 hz pit
   4974 	outb(IO_PIT + 3, 0x36);
   4975 	outb(IO_PIT + 0, 0xa9);
   4976 	outb(IO_PIT + 0, 0x04);
   4977 
   4978 	// unmask pit
   4979 	outb(IO_PIC1 + 1, 0xfe);
   4980 	outb(IO_PIC2 + 1, 0xff);
   4981 
   4982 	// Allocate network state tables
   4983 	global.arp = alloc() as *arp_entry;
   4984 	global.arp_count = 4096 / sizeof(*global.arp);
   4985 	global.tcp = alloc() as **tcp_state;
   4986 	global.tcp_count = 4096 / sizeof(*global.tcp);
   4987 	bzero(global.arp as *byte, 4096);
   4988 	bzero(global.tcp as *byte, 4096);
   4989 
   4990 	read_rtc();
   4991 	sti();
   4992 
   4993 	// Find ACPI tables
   4994 	rsdt = find_rsdt();
   4995 	if !rsdt {
   4996 		kdie("No rsdt?\n");
   4997 	}
   4998 
   4999 	mcfg = find_acpi(rsdt, "MCFG");
   5000 	if !mcfg {
   5001 		kdie("No mcfg?\n");
   5002 	}
   5003 
   5004 	pcip = (ptov(mcfg + 44) as *int)[0];
   5005 	if !pcip {
   5006 		kdie("No pci?\n");
   5007 	}
   5008 
   5009 	// Enable the local apic
   5010 	var lapicp: int;
   5011 	lapicp = rdmsr(0x1b) & -4096;
   5012 	var lapic: *byte;
   5013 	lapic = map_pci(lapicp);
   5014 	_w32(&lapic[0xf0], _r32(&lapic[0xf0]) | 0x1ff);
   5015 	global.lapicp = lapicp;
   5016 	global.lapic = lapic;
   5017 
   5018 	pci = map_pci(pcip);
   5019 	scan_pci(pci, show_pcidev);
   5020 	//scan_pci(pci, init_realtek);
   5021 	//scan_pci(pci, init_ahci);
   5022 
   5023 
   5024 	//tcp_listen(22, tcp_ssh);
   5025 
   5026 	//parse_initramfs();
   5027 
   5028 	//spawn(task_init, "init", nil);
   5029 
   5030 	// Wait for interrupts
   5031 	kputs("zzz\n");
   5032 	loop {
   5033 		if global.curtask.next == global.curtask {
   5034 			hlt();
   5035 		}
   5036 		yield();
   5037 	}
   5038 }