os

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

commit afb43b59137edc9507341270674c11f7f5431ee6
parent 778abaa4a0c04cb4227d5ce01f6f9c1508a85032
Author: erai <erai@omiltem.net>
Date:   Sun, 28 Apr 2024 01:34:53 -0400

dumb rtl 10ec:8168

Diffstat:
Mas.c | 5+++++
Mcc1.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mkernel.c | 890++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mpxe.asm | 26++++++++++++++------------
4 files changed, 843 insertions(+), 133 deletions(-)

diff --git a/as.c b/as.c @@ -54,12 +54,17 @@ enum { } enum { + OP_GS = 0x65, + OP_OS = 0x66, + OP_CLD = 0xfc, OP_CLI = 0xfa, OP_STI = 0xfb, OP_CPUID = 0x0fa2, OP_IN = 0xec, + OP_IND = 0xed, OP_OUT = 0xee, + OP_OUTD = 0xef, OP_HLT = 0xf4, OP_NOP = 0x90, OP_WBINVD = 0x0f09, diff --git a/cc1.c b/cc1.c @@ -1527,6 +1527,50 @@ main(argc: int, argv: **byte, envp: **byte) { emit_ret(c.as); } + d = find(c, "inw", 0:*byte, 1); + if (d.func_defined && !d.func_label.fixed) { + fixup_label(c.as, d.func_label); + emit_preamble(c.as, 0, 0); + as_modrm(c.as, OP_LOAD, R_RDX, R_RBP, 0, 0, 16); + as_emit(c.as, OP_OS); + as_op(c.as, OP_IND); + as_opr(c.as, OP_PUSHR, R_RAX); + emit_ret(c.as); + } + + d = find(c, "outw", 0:*byte, 1); + if (d.func_defined && !d.func_label.fixed) { + fixup_label(c.as, d.func_label); + emit_preamble(c.as, 0, 0); + as_modrm(c.as, OP_LOAD, R_RDX, R_RBP, 0, 0, 16); + as_modrm(c.as, OP_LOAD, R_RAX, R_RBP, 0, 0, 24); + as_emit(c.as, OP_OS); + as_op(c.as, OP_OUTD); + as_opr(c.as, OP_PUSHR, R_RAX); + emit_ret(c.as); + } + + d = find(c, "ind", 0:*byte, 1); + if (d.func_defined && !d.func_label.fixed) { + fixup_label(c.as, d.func_label); + emit_preamble(c.as, 0, 0); + as_modrm(c.as, OP_LOAD, R_RDX, R_RBP, 0, 0, 16); + as_op(c.as, OP_IND); + as_opr(c.as, OP_PUSHR, R_RAX); + emit_ret(c.as); + } + + d = find(c, "outd", 0:*byte, 1); + if (d.func_defined && !d.func_label.fixed) { + fixup_label(c.as, d.func_label); + emit_preamble(c.as, 0, 0); + as_modrm(c.as, OP_LOAD, R_RDX, R_RBP, 0, 0, 16); + as_modrm(c.as, OP_LOAD, R_RAX, R_RBP, 0, 0, 24); + as_op(c.as, OP_OUTD); + as_opr(c.as, OP_PUSHR, R_RAX); + emit_ret(c.as); + } + d = find(c, "rdmsr", 0:*byte, 1); if (d.func_defined && !d.func_label.fixed) { fixup_label(c.as, d.func_label); @@ -1789,6 +1833,17 @@ main(argc: int, argv: **byte, envp: **byte) { emit_isr(c); } + d = find(c, "_rgs", 0:*byte, 1); + if (d.func_defined && !d.func_label.fixed) { + fixup_label(c.as, d.func_label); + emit_preamble(c.as, 0, 0); + as_modrm(c.as, OP_LOAD, R_RSI, R_RBP, 0, 0, 16); + as_emit(c.as, OP_GS); + as_modrm(c.as, OP_LOAD, R_RAX, R_RSI, 0, 0, 0); + as_opr(c.as, OP_PUSHR, R_RAX); + emit_ret(c.as); + } + d = find(c, "_r32", 0:*byte, 1); if (d.func_defined && !d.func_label.fixed) { fixup_label(c.as, d.func_label); diff --git a/kernel.c b/kernel.c @@ -5,6 +5,12 @@ cpuid(a: *int, c: *int, d: *int, b: *int); inb(a: int): int; outb(a: int, x: int); +inw(a: int): int; +outw(a: int, x: int); + +ind(a: int): int; +outd(a: int, x: int); + rdmsr(r: int): int; wrmsr(r: int, x: int); @@ -35,6 +41,8 @@ invlpg(x: int); _isr0(); +_rgs(x: int): int; + struct regs { rax: int; // 0 rcx: int; // 8 @@ -183,50 +191,40 @@ bzero(s: *byte, size: int) { } _isr(r: *regs) { - if (r.trap < 32) { - //sputs("EX "); - //sputd(r.trap); - //sputs("\n"); - } + var global: *global; + global = g(); - if (r.trap == 2) { - //sputs("NMI\n"); - } - - var vga: *byte; - - vga = ptov(0xB8000); - - vga[2] = ('A' + r.trap):byte; - vga[3] = 0x0e:byte; - - // pic end of interrupt - if (r.trap >= 32 && r.trap < 48) { + if (r.trap < 32) { + kputs("EX "); + kputd(r.trap); + kputs("\n"); + } else { if (r.trap == 32) { - } else if (r.trap == 42) { - //sputc('n'); - //sputc('\n'); - } else if (r.trap == 43) { - // ethernet interrupt - //sputc('e'); - } - if (r.trap < 40) { - outb(IO_PIC1, 0x0b); - if inb(IO_PIC1) & (1 << (r.trap & 7)) { - outb(IO_PIC1, 0x20); - } else { - //sputs("s\n"); - } - } else { - outb(IO_PIC2, 0x0b); - if inb(IO_PIC2) & (1 << (r.trap & 7)) { - outb(IO_PIC2, 0x20); - outb(IO_PIC1, 0x20); - } else { - //sputs("s\n"); - } + isr_realtek(); } + // apic end of interrupt + _w32(&global.lapic[0xb0], 0); } + + // pic end of interrupt + //if (r.trap >= 32 && r.trap < 48) { + // if (r.trap < 40) { + // outb(IO_PIC1, 0x0b); + // if inb(IO_PIC1) & (1 << (r.trap & 7)) { + // outb(IO_PIC1, 0x20); + // } else { + // kputs("s\n"); + // } + // } else { + // outb(IO_PIC2, 0x0b); + // if inb(IO_PIC2) & (1 << (r.trap & 7)) { + // outb(IO_PIC2, 0x20); + // outb(IO_PIC1, 0x20); + // } else { + // kputs("s\n"); + // } + // } + //} } fill_idt(s: *int) { @@ -286,7 +284,11 @@ bytesum(a: *byte, n: int): byte { } ptov(p: int): *byte { - return (p + (-0x8000 << 16)): *byte; + if p < (1 << 30) { + return (p + (-0x8000 << 16)): *byte; + } else { + return (p + (-1 << 47)): *byte; + } } acpi_len(p: int): int { @@ -318,79 +320,120 @@ valid_table(p: int, sig: *byte): int { return len; } -show_addr(x: int) { - var vga: *byte; - var i: int; - var j: int; +kputh(x: int) { + _kputh(x, 64); +} + +kputh8(x: int) { + _kputh(x, 8); +} - vga = ptov(0xB8000); +kputh16(x: int) { + _kputh(x, 16); +} + +kputh32(x: int) { + _kputh(x, 32); +} - i = 64; - j = 160; +_kputh(x: int, d: int) { loop { - if i == 0 { + if d == 0 { break; } - i = i - 4; - vga[j] = "0123456789abcdef"[(x >> i) & 15]; - vga[j + 1] = 0x0e:byte; - j = j + 2; + d = d - 4; + kputc("0123456789abcdef"[(x >> d) & 15]:int); + } +} + +kputd(x: int) { + var a: int; + + if x < 0 { + kputc('-'); + a = -(x % 10); + x = x / -10; + } else { + a = x % 10; + x = x / 10; + } + + if x != 0 { + kputd(x); } + kputc('0' + a); } find_xsdt(): int { var p: int; + var v: *byte; + var len: int; // Find the RDSP p = 0xe0000; loop { + v = ptov(p); + if p + 20 >= 0xfffff { return 0; } - if !memcmp(ptov(p), "RSD PTR ", 8) { - if !bytesum(ptov(p), 20) { + + if !memcmp(v, "RSD PTR ", 8) { + if !bytesum(v, 20) { break; } } + p = p + 16; } - //p = _r32(ptov(p + 16)); + // Revision + if v[15]:int != 2 { + return 0; + } - p = ptov(p + 24):*int[0]; - show_addr(p); - //if valid_table(p, "XSDT") == 0 { - //return 0; - //} + len = _r32(&v[20]); + if len < 36 || len > 128 { + return 0; + } + + if bytesum(v, len) { + return 0; + } + + p = (&v[24]):*int[0]; + if valid_table(p, "XSDT") == 0 { + return 0; + } return p; } -find_acpi(rsdt: int, sig: *byte): int { +find_acpi(xsdt: int, sig: *byte): int { var i: int; var len: int; var p: int; - if rsdt == 0 { + if xsdt == 0 { return 0; } i = 36; - len = acpi_len(rsdt); + len = acpi_len(xsdt); loop { if i >= len { return 0; } - p = _r32(ptov(rsdt + i)); + p = ptov(xsdt + i):*int[0]; if valid_table(p, sig) != 0 { return p; } - i = i + 4; + i = i + 8; } } @@ -412,8 +455,8 @@ map_pci(va: *byte, pa: int): *byte { } struct pcidev { - user: *void; addr: *byte; + type: int; bus: int; vid: int; did: int; @@ -426,21 +469,25 @@ struct pcidev { bar4: int; bar5: int; trap: *byte; + msi: *byte; } -scan_pci(base: *byte, visit: func(dev: *pcidev), user: *void) { +scan_pci(base: *byte, visit: func(dev: *pcidev)) { var i: int; + var cap: int; + var capid: int; var dev: pcidev; i = 0; loop { - if i == 256 { + if i == 256*64 { break; } - dev.user = user; dev.addr = &base[i * 4096]; dev.bus = i; + dev.type = base[i * 4096 + 14]:int; + dev.vid = (base[i * 4096 + 0]:int) + (base[i * 4096 + 1]:int << 8); dev.did = (base[i * 4096 + 2]:int) @@ -461,41 +508,55 @@ scan_pci(base: *byte, visit: func(dev: *pcidev), user: *void) { continue; } + dev.msi = 0:*byte; + + if dev.type == 0 { + cap = base[i * 4096 + 0x34]: int; + loop { + if cap == 0 || cap > 4094 { + break; + } + + capid = base[i * 4096 + cap]:int; + + if capid == 5 { + dev.msi = &base[i * 4096 + cap]; + } + + cap = base[i * 4096 + cap + 1]:int; + } + } + visit(&dev); i = i + 1; } } -clear_int(dev: *pcidev) { - *dev.trap = 0xff:byte; - _w16(&dev.addr[4], 0); -} - show_pcidev(dev: *pcidev) { - sputh(dev.bus); - sputc(':'); - sputc('\t'); - sputh(dev.vid); - sputc(':'); - sputh(dev.did); - sputc('\t'); - sputh(dev.cls); - sputc(':'); - sputh(dev.subcls); - sputc('\t'); - sputh(dev.bar0); - sputc('\t'); - sputh(dev.bar1); - sputc('\t'); - sputh(dev.bar2); - sputc('\t'); - sputh(dev.bar3); - sputc('\t'); - sputh(dev.bar4); - sputc('\t'); - sputh(dev.bar5); - sputc('\n'); + kputh16(dev.bus); + kputc(':'); + kputc(' '); + kputh16(dev.vid); + kputc(':'); + kputh16(dev.did); + kputc(' '); + kputh8(dev.cls); + kputc(':'); + kputh8(dev.subcls); + kputc(' '); + kputh32(dev.bar0); + kputc(' '); + kputh32(dev.bar1); + kputc(' '); + kputh32(dev.bar2); + kputc(' '); + kputh32(dev.bar3); + kputc(' '); + kputh32(dev.bar4); + kputc(' '); + kputh32(dev.bar5); + kputc('\n'); } map_bar(va: *byte, dev: *pcidev): *byte { @@ -579,7 +640,6 @@ init_e1000(dev: *pcidev) { var i: int; var txring: *byte; - flag = dev.user: *int; if *flag || dev.vid != 0x8086 || ( dev.did != 0x100e && dev.did != 0x1539 @@ -729,7 +789,6 @@ init_nvme(dev: *pcidev) { var flag: *int; var base: *byte; - flag = dev.user: *int; if *flag || dev.cls != 1 || dev.subcls != 8 { return; } @@ -745,15 +804,533 @@ init_nvme(dev: *pcidev) { return; } - sputs("nvme\n"); + kputs("nvme\n"); // setup admin ring // enable interrupts +} + +struct vga { + base: *byte; + cx: int; + cy: int; + x: int; + y: int; +} + +vinit(v: *vga, base: *byte) { + v.base = base; + v.cx = 80; + v.cy = 25; + v.x = 0; + v.y = 0; +} + +vcursor(v: *vga) { + var i: int; + i = v.y * v.cx + v.x; + outb(0x3d4, 0x0f); + outb(0x3d5, i); + outb(0x3d4, 0x0e); + outb(0x3d5, i >> 8); +} + +vclear(v: *vga) { + var i: int; + v.x = 0; + v.y = 0; + vcursor(v); + i = 0; + loop { + if i == v.cx * v.cy { + return; + } + v.base[2 * i] = 0:byte; + v.base[2 * i + 1] = 0x0f:byte; + i = i + 1; + } +} +vshift(v: *vga) { + var i: int; + memcpy(v.base, &v.base[v.cx * 2], (v.cy - 1) * v.cx * 2); + i = (v.cy - 1) * v.cx; + loop { + if i == v.cx * v.cy { + break; + } + v.base[2 * i] = 0:byte; + v.base[2 * i + 1] = 0x0f:byte; + i = i + 1; + } + if v.y > 0 { + v.y = v.y - 1; + } +} + +vputc(v: *vga, c: int) { + if c == '\r' { + v.x = 0; + } else if c == '\n' { + v.x = 0; + v.y = v.y + 1; + if v.y == v.cy { + vshift(v); + } + } else { + v.base[(v.y * v.cx + v.x) * 2] = c:byte; + v.base[(v.y * v.cx + v.x) * 2 + 1] = 0x0f:byte; + v.x = v.x + 1; + if v.x == v.cx { + v.x = 0; + v.y = v.y + 1; + if v.y == v.cy { + vshift(v); + } + } + } + vcursor(v); +} + +kputc(c: int) { + var global: *global; + global = g(); + vputc(&global.vga, c); +} + +kputs(s: *byte) { + var i: int; + var global: *global; + global = g(); + i = 0; + loop { + if !s[i] { + break; + } + vputc(&global.vga, s[i]:int); + i = i + 1; + } +} + +struct global { + ptr: *global; + vga: vga; + fr: *free_range; + fpage: *free_page; + lapicp: int; + lapic: *byte; + rtkio: int; + rxring: int; + txring: int; +} + +struct free_page { + next: *free_page; +} + +struct free_range { + next: *free_range; + start: int; + end: int; +} + +g(): *global { + return _rgs(0):**global[0]; +} + +memset(dest: *byte, c: int, size: int) { + var i: int; + + if size < 0 { + return; + } + + i = 0; + loop { + if i == size { + break; + } + dest[i] = c:byte; + i = i + 1; + } +} +memcpy(dest: *byte, src: *byte, size: int) { + var i: int; + + if size < 0 { + return; + } + + if src > dest { + i = 0; + loop { + if i == size { + break; + } + dest[i] = src[i]; + i = i + 1; + } + } else if src < dest { + i = size; + loop { + if i == 0 { + break; + } + i = i - 1; + dest[i] = src[i]; + } + } +} + +memswap(a: *byte, b: *byte, size: int) { + var i: int; + var t: byte; + + if size < 0 { + return; + } + + i = 0; + loop { + if i == size { + break; + } + t = a[i]; + a[i] = b[i]; + b[i] = t; + i = i + 1; + } +} + +insert_sort(arr: *void, nitems: int, size: int, cmp: (func(a: *void, b: *void): int)) { + var i: int; + var j: int; + var a: *void; + var b: *void; + + if nitems <= 1 || size <= 0 { + return; + } + + i = 1; + loop { + if i == nitems { + break; + } + + j = i - 1; + + b = (&arr:*byte[size * i]):*void; + + loop { + a = (&arr:*byte[size * j]):*void; + + if cmp(a, b) <= 0 { + break; + } + + memswap(a: *byte, b: *byte, size); + + if j == 0 { + break; + } + + j = j - 1; + } + + i = i + 1; + } +} + +mmap_cmp(a: *void, b: *void): int { + var a_addr: int; + var b_addr: int; + a_addr = a:*int[0]; + b_addr = b:*int[0]; + if a_addr < b_addr { + return -1; + } else if a_addr > b_addr { + return 1; + } + return 0; +} + +alloc_page(): int { + var global: *global; + var fr: *free_range; + var ret: int; + global = g(); + fr = global.fr; + loop { + if !fr { + break; + } + + if fr.start < fr.end { + ret = fr.start; + fr.start = fr.start + 4096; + return ret; + } + + fr = fr.next; + } + + kputs("OOM\n"); + + loop { + cli(); + hlt(); + } +} + +direct_map(brk: *int) { + var pt4p: int; + var pt4: *int; + var pt3p: int; + var pt3: *int; + var va: int; + var pa: int; + var page_size: int; + var map_size: int; + var i: int; + var n: int; + + map_size = 1 << 46; + page_size = 1 << 30; + + va = -1 << 47; + pa = 0; + + pt4p = rdcr3(); + pt4 = ptov(pt4p):*int; + + brk[0] = (brk[0] + 4095) & -4096; + + loop { + if pa == map_size { + break; + } + + n = 512; + + pt3 = brk[0]:*int; + brk[0] = brk[0] + 4096; + pt3p = (pt3:int) & ((1 << 31) - 1); + + i = (va >> 39) & 511; + pt4[i] = pt3p | 0x003; + + loop { + if pa == map_size || n == 0 { + break; + } + + i = (va >> 30) & 511; + pt3[i] = pa | 0x083; + + va = va + page_size; + pa = pa + page_size; + n = n - 1; + } + } + + wrcr3(pt4p); +} + +setup_ring(ring: int, own: int) { + var v: *byte; + var i: int; + var p: int; + + v = ptov(ring); + i = 0; + + loop { + if i == 16 { + break; + } + + p = alloc_page(); + + _w32(&v[i * 16], (own << 31) | ((i == 15) << 30) | 4096); + _w32(&v[i * 16 + 4], 0); + _w32(&v[i * 16 + 8], p); + _w32(&v[i * 16 + 12], p >> 32); + + i = i + 1; + } +} + +fill_packet(ringp: int) { + var ring: *byte; + var packet: *byte; + + ring = ptov(ringp); + packet = ptov(ring:*int[1]); + + // Send a packet + packet[0] = 0xff:byte; + packet[1] = 0xff:byte; + packet[2] = 0xff:byte; + packet[3] = 0xff:byte; + packet[4] = 0xff:byte; + packet[5] = 0xff:byte; + packet[6] = 0xff:byte; + packet[7] = 0xff:byte; + packet[8] = 0xff:byte; + packet[9] = 0xff:byte; + packet[10] = 0xff:byte; + packet[11] = 0xff:byte; + packet[12] = 0x08:byte; + packet[13] = 0x00:byte; + + packet[14] = 0x45:byte; + packet[15] = 0:byte; + packet[16] = 0:byte; + packet[17] = 28:byte; + packet[18] = 0:byte; + packet[19] = 0:byte; + packet[20] = 0:byte; + packet[21] = 0:byte; + packet[22] = 64:byte; + packet[23] = 1:byte; + packet[24] = 0:byte; + packet[25] = 0:byte; + packet[26] = 192:byte; + packet[27] = 168:byte; + packet[28] = 2:byte; + packet[29] = 100:byte; + packet[30] = 192:byte; + packet[31] = 168:byte; + packet[32] = 1:byte; + packet[33] = 178:byte; + + ip_checksum(&packet[14]); + + packet[34] = 8:byte; + packet[35] = 0:byte; + packet[36] = 0:byte; + packet[37] = 0:byte; + packet[38] = 0:byte; + packet[39] = 0:byte; + packet[40] = 0:byte; + + icmp_checksum(&packet[34]); + + ring:*int[0] = (0xb000 << 16) + (64); +} + +init_realtek(dev: *pcidev) { + var global: *global; + var io: int; + var pg: int; + + global = g(); + + if dev.vid != 0x10ec || dev.did != 0x8168 { + return; + } + + io = dev.bar0 & -2; + global.rtkio = io; + + // Enable dma + _w16(&dev.addr[4], 7); + + // Reset + outb(io + 0x37, 0x10); + loop { + if (inb(io + 0x37) & 0x10) == 0 { + break; + } + } + + // Setup MSI + _w16(&dev.msi[2], 0x0081); + _w32(&dev.msi[4], global.lapicp); + _w32(&dev.msi[8], 0); + _w16(&dev.msi[12], 32); + + // Config write enable + outb(io + 0x50, 0xc0); + + // rx config + outd(io + 0x44, 0x0000e70f); + + // tx config + outb(io + 0x37, 0x0c); + outd(io + 0x40, 0x03000700); + + // rx packet size + outd(io + 0xda, 0x00000800); + + // tx packet size + outd(io + 0xec, 0x00000010); + + pg = alloc_page(); + setup_ring(pg, 0); + fill_packet(pg); + global.txring = pg; + + // tx ring + outd(io + 0x20, pg); + outd(io + 0x24, pg >> 32); + + // tx max size + outb(io + 0xec, 16); + + pg = alloc_page(); + setup_ring(pg, 1); + global.rxring = pg; + + // rx ring + outd(io + 0xe4, pg); + outd(io + 0xe8, pg >> 32); + + // Enable rx/tx + outd(io + 0x37, 0x0c); + + // Enable interrupts + outw(io + 0x3c, 0x00ff); + outw(io + 0x3e, 0xffff); + + // Config write disable + outb(io + 0x50, 0x00); + + // TX Doorbell + outb(io + 0x38, 0x40); +} + +isr_realtek() { + var v: *byte; + var global: *global; + var i: int; + + global = g(); + + v = ptov(global.rxring); + + i = 0; + loop { + if i == 16 { + break; + } + + _w32(&v[i * 16], (1 << 31) | ((i == 15) << 30) | 4096); + _w32(&v[i * 16 + 4], 0); + + i = i + 1; + } + + kputc('.'); + + // clear interrupt flags + outw(global.rtkio + 0x3e, 0xffff); } _kstart(mb: int) { + var global: global; var brk: int; var tss: *int; var tss_size: int; @@ -766,16 +1343,73 @@ _kstart(mb: int) { var pcip: int; var pci: *byte; var flag: int; - var vga: *byte; + var mbinfo: *byte; + var mmap: *int; + var mmap_len: int; + var mmap_count: int; + var fr: *free_range; + + global.ptr = &global; + wrmsr((0xc000 << 16) + 0x0101, global.ptr:int); + + vinit(&global.vga, ptov(0xB8000)); + vclear(&global.vga); + kputs("Starting up\n"); + + global.fr = 0:*free_range; + + brk = ptov(1024 * 1024 * 3):int; + + mbinfo = ptov(mb); + mmap = ptov(_r32(&mbinfo[48])): *int; + mmap_len = _r32(&mbinfo[44]); + mmap_count = mmap_len / 24; + + insert_sort(mmap:*void, mmap_count, 24, mmap_cmp); + + var i: int; + var mmap_start: int; + var mmap_end: int; + i = 0; + loop { + if i == mmap_count { + break; + } + + mmap_start = mmap[i * 3]; + mmap_end = mmap_start + mmap[i * 3 + 1]; + + if i + 1 < mmap_count { + if mmap_end > mmap[i * 3 + 3] { + kputs("panic: OVERLAP\n"); + loop { + cli(); + hlt(); + } + } + } + + mmap_start = (mmap_start + 4095) & -4096; + mmap_end = mmap_end & -4096; - vga = ptov(0xB8000); + if mmap_start < 0x400000 { + mmap_start = 0x400000; + } - vga[0] = 'a':byte; - vga[1] = 0x0e:byte; + if mmap_start < mmap_end && _r32((&mmap[i * 3 + 2]):*byte) == 1 { + fr = brk: *free_range; + brk = brk + sizeof(*fr); + fr.next = global.fr; + fr.start = mmap_start; + fr.end = mmap_end; + global.fr = fr; + } - //setup_serial(); + i = i + 1; + } - brk = ptov(1024 * 512 * 3):int; + // Directly map all memory to just above the architectural hole + direct_map(&brk); // Zero tss and add interrupt stacks tss = brk: *int; @@ -808,6 +1442,7 @@ _kstart(mb: int) { // Load gdt idt tss and segments lgdt(gdt, gdt_size); lseg(8, 16); + wrmsr((0xc000 << 16) + 0x0101, global.ptr:int); lldt(0); ltr(5 * 8); lidt(idt, idt_size); @@ -848,28 +1483,41 @@ _kstart(mb: int) { outb(IO_PIT + 0, 0x9b); outb(IO_PIT + 0, 0x2e); - // unmask pit - outb(IO_PIC1 + 1, 0xfa); - outb(IO_PIC2 + 1, 0xf3); + // Disable serial ports + outb(0x3f8 + 1, 0x00); + outb(0x2f8 + 1, 0x00); - show_addr(ptov(mb + 44):*int[0]); + // unmask pit + outb(IO_PIC1 + 1, 0xff); + outb(IO_PIC2 + 1, 0xff); // Find ACPI tables - //xsdt = find_xsdt(); + xsdt = find_xsdt(); + mcfg = find_acpi(xsdt, "MCFG"); + if !mcfg { + kputs("No mcfg?\n"); + } - //mcfg = find_acpi(xsdt, "MCFG"); + pcip = (ptov(mcfg + 44):*int)[0]; + if !pcip { + kputs("No pci?\n"); + } - //pcip = (ptov(mcfg + 44):*int)[0]; - //pci = map_pci(ptov(-(1<<31)), pcip); + // Enable the local apic + var lapicp: int; + lapicp = rdmsr(0x1b) & -4096; + var lapic: *byte; + lapic = map_pci(ptov(-32 << 30), lapicp); + _w32(&lapic[0xf0], _r32(&lapic[0xf0]) | 0x1ff); + global.lapicp = lapicp; + global.lapic = lapic; - //scan_pci(pci, show_pcidev, 0:*void); - //scan_pci(pci, clear_int, 0:*void); - //flag = 0; - //scan_pci(pci, init_e1000, (&flag):*void); - //flag = 0; - //scan_pci(pci, init_nvme, (&flag):*void); + pci = map_pci(ptov(-34 << 30), pcip); + scan_pci(pci, show_pcidev); + scan_pci(pci, init_realtek); // Wait for interrupts + kputs("Sleeping...\n"); loop { sti(); hlt(); diff --git a/pxe.asm b/pxe.asm @@ -196,6 +196,8 @@ detect_mem: .1: pop bp sub bp, .1 + push cs + pop es ; BIOS - Get memory size clc int 0x12 @@ -204,7 +206,7 @@ detect_mem: xor eax, eax pop ax shl eax, 10 - mov cs:[bp + low_mem_size], eax + mov es:[bp + low_mem_size], eax ; BIOS - Get high memory size mov ah, 0x88 clc @@ -214,13 +216,13 @@ detect_mem: xor eax, eax pop ax shl eax, 10 - mov cs:[bp + high_mem_size], eax + mov es:[bp + high_mem_size], eax ; Zero kernel size - mov dword cs:[bp + kernel_size], 0 + mov dword es:[bp + kernel_size], 0 mov di, bp add di, mmap + 4 mov ebx, 0 - mov word cs:[bp + mmap_size], 0 + mov word es:[bp + mmap_size], 0 .loop: ; BIOS - Get system memory map mov edx, 0x534D4150 @@ -234,9 +236,9 @@ detect_mem: jnz .no_mem cmp ecx, 20 jnz .no_mem - mov cs:[di - 4], ecx - add word cs:[bp + mmap_size], 24 - cmp word cs:[bp + mmap_size], (mmap_end - mmap) + mov es:[di - 4], ecx + add word es:[bp + mmap_size], 24 + cmp word es:[bp + mmap_size], (mmap_end - mmap) jz .no_mem add di, 24 test ebx, ebx @@ -268,7 +270,6 @@ enter_unreal: .1: xor ebx, ebx pop bx - ; Load the gdt sub sp, 6 mov bp, sp @@ -797,7 +798,8 @@ parse_mb: mov dword ds:[edi + 8], eax ; Save mmap_len - mov eax, cs:[bx + mmap_size - .1] + xor eax, eax + mov ax, cs:[bx + mmap_size - .1] mov dword ds:[edi + 44], eax ; Save mmap_addr @@ -805,7 +807,7 @@ parse_mb: mov ax, cs shl eax, 4 add eax, ebx - mov eax, (mmap - .1) + add eax, (mmap + 4 - .1) mov dword ds:[edi + 48], eax popf @@ -993,5 +995,5 @@ frame equ $ page equ frame + 256 ;times 512 db 0 mmap equ page + 512 - ;times 8192 db 0 -mmap_end equ mmap + 8192 + ;times (8192 + 8192) db 0 +mmap_end equ mmap + (8192 + 8192)