diff --git a/kernel/src/arch/i386/i386.zig b/kernel/src/arch/i386/i386.zig new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/arch/i386/info.c b/kernel/src/arch/i386/info.c index 923fad0..19ab434 100644 --- a/kernel/src/arch/i386/info.c +++ b/kernel/src/arch/i386/info.c @@ -1,2 +1 @@ - extern char archval; - const char *arch = &archval; +const char *arch = "i386"; diff --git a/kernel/src/arch/i386/info.s b/kernel/src/arch/i386/info.s deleted file mode 100644 index b0590cc..0000000 --- a/kernel/src/arch/i386/info.s +++ /dev/null @@ -1,3 +0,0 @@ -.global archval -archval: - .asciz "i386-gas" \ No newline at end of file diff --git a/kernel/src/arch/x86/x86.zig b/kernel/src/arch/x86/x86.zig new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/arch/x86_64/interrupt.c b/kernel/src/arch/x86_64/interrupt.c index faa9c92..442b64e 100644 --- a/kernel/src/arch/x86_64/interrupt.c +++ b/kernel/src/arch/x86_64/interrupt.c @@ -5,8 +5,6 @@ typedef uint64_t uword_t; -extern void isr_wrapper(); - struct interrupt_frame { uword_t ip; @@ -16,22 +14,13 @@ struct interrupt_frame uword_t ss; }; -void interrupt_handler() -{ - printf("interrupted\n"); - // panic("ee"); -} - +// zig function +void setup_idt(); void setup_ints() { - set_idt_ent(0x80, (uint64_t)&isr_wrapper, 0, 0, INT64); - init_idt(); - - typedef void (*MyFunctionType)(void); - MyFunctionType handler_0x80 = get_idt_fn(0x80); - printf("interrupt handler: %x\n", handler_0x80); - // interrupt_handler(0); - + setup_idt(); + init_idt(); + set_idt_ent(0x80, (uint64_t)&isr_wrapper128, 0, 0, INT64); __asm__ volatile("int $0x80"); diff --git a/kernel/src/arch/x86_64/interrupt.zig b/kernel/src/arch/x86_64/interrupt.zig new file mode 100644 index 0000000..898fabd --- /dev/null +++ b/kernel/src/arch/x86_64/interrupt.zig @@ -0,0 +1,43 @@ +const std = @import("std"); + +const c_idt = @cImport(@cInclude("arch/x86_64/idt.h")); + +export const int_msg = "INTERRUPTED!\n"; + +comptime { + @setEvalBranchQuota(2560000); + comptime var i = 0; + var buf: [512]u8 = undefined; + inline while (i < 256) : (i += 1) { + const code = std.fmt.bufPrint(buf[0..512], + \\.global isr_wrapper{} + \\.type isr_wrapper{}, @function + \\isr_wrapper{}: + \\ mov ${}, %rdi + \\ call interrupt_handler + \\ iretq + , .{i,i,i,i}) catch unreachable; + asm (code); + } +} + +export fn interrupt_handler(int_type: u64) void { + var buf: [128]u8 = undefined; + const msg = std.fmt.bufPrint(std.mem.span(&buf), "INTERRUPTED: 0x{x}", .{int_type}) catch "Interrupted, error printing message"; + std.log.warn("{}", .{msg}); + if(int_type != 0x80) + @panic(msg); +} + +export fn setup_idt() void { + @setEvalBranchQuota(256000); + comptime var i = 0; + comptime var buf: [128]u8 = undefined; + inline while (i <= 0xFF) : (i += 1) { + comptime const asmcode = std.fmt.bufPrint(buf[0..128], "mov $isr_wrapper{}, %%rax", .{i}) catch unreachable; + const wrapper = asm(asmcode + : [ret] "={rax}" (->usize) :: + ); + c_idt.set_idt_ent(i, wrapper, 0, 0, @intToEnum(c_idt.GateType, c_idt.INT64)); + } +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/paging.zig b/kernel/src/arch/x86_64/paging.zig new file mode 100644 index 0000000..1de2aa4 --- /dev/null +++ b/kernel/src/arch/x86_64/paging.zig @@ -0,0 +1,55 @@ +const std = @import("std"); + +pub const page_entry_flags = packed struct { + present: bool, /// page is present in physmem? + rw: bool, /// page can be written to? + user: bool, /// page accessible by userland? + pwt: bool, /// ??? + pcd: bool, /// ??? + accessed: bool, /// maybe useful for paging? + dirty: bool, /// (ONLY PAGE) maybe useful for paging (esp if re-paging?) + page_size: bool = true, /// this is an actual page (not a table pointer) (or PAT for 4k page) + global: bool, /// (ONLY PAGE) is this page global? (used by TLB buffer) +}; + +pub const page_table_entry = packed struct { + flags: page_entry_flags, + avl: u3, /// OS available bits + addr: u40, /// address of the page (4K aligned, trimmed) + avail: u7, /// are these free? + mpk: u4, /// ??? + nx: bool, /// No Execute +}; + + +// const page_table_default: page_table_entry = .{ +// .nx = 0, .avail = 0, .addr = 0, .avl = 0, .pcd=0, .pwt=0, .user=0, .rw=1, .present=0 +// }; + +pub const page_lvl4_table align(4096) = [_]page_table_entry{page_table_default} ** 512; + +pub fn showTable(tbl: [512]u64) void { + // const page_table_wrapped = packed struct {p: page_table_entry}; + const page_table_entry1 = packed struct {p: page_table_entry, u: u1}; + const page_table_entry7 = packed struct {p: page_table_entry, u: u7}; + std.log.info("pgtbl_entry_size = {} {} {} {}", .{@sizeOf(page_table_entry), @sizeOf(u64), @sizeOf(page_table_entry1), @sizeOf(page_table_entry7)}); + + + // const pag0 = @bitCast(page_table_entry, @intCast(u64, 1)); + // std.log.info("PAG0 = {}", .{pag0}); + + for(tbl) |ent, i| { + const e = @bitCast(page_table_entry, ent); + if(e.flags.present) + std.log.debug( + "PAGTBL {}: {} = {x}", + .{i,e, e.addr * 4096}); + } +} + + +test "page_entry_size" { + std.testing.expectEqual(8, @sizeOf(page_table_entry)); + std.testing.expectEqual(9, @sizeOf(struct{t: page_table_entry, p:u1})); + showLvl4(page_lvl4_table); +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/panic.nasminc b/kernel/src/arch/x86_64/panic.nasminc index feccb6c..46a3dc6 100644 --- a/kernel/src/arch/x86_64/panic.nasminc +++ b/kernel/src/arch/x86_64/panic.nasminc @@ -14,4 +14,3 @@ call panic %endmacro %endif - \ No newline at end of file diff --git a/kernel/src/arch/x86_64/x86_64.zig b/kernel/src/arch/x86_64/x86_64.zig new file mode 100644 index 0000000..f4a31e0 --- /dev/null +++ b/kernel/src/arch/x86_64/x86_64.zig @@ -0,0 +1,7 @@ +const x86 = @import("src/arch/x86/x86.zig"); +pub const paging = @import("paging.zig"); +pub const interrupt = @import("interrupt.zig"); + +comptime { + _ = interrupt; +} \ No newline at end of file diff --git a/kernel/src/main.zig b/kernel/src/main.zig index ca9be3b..1e84e76 100644 --- a/kernel/src/main.zig +++ b/kernel/src/main.zig @@ -4,6 +4,16 @@ const debug = @import("debug.zig"); const kalloc = @import("allocator/kalloc.zig"); const time = @import("time.zig"); +const arch = switch(builtin.cpu.arch) { + .x86_64 => @import("arch/x86_64/x86_64.zig"), + .i386 => @import("arch/i386/i386.zig"), + else => @panic("unknown architecture!"), +}; + +comptime { + _ = arch; +} + pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn { debug.zigpanic(msg, error_return_trace); } @@ -46,12 +56,22 @@ export fn zigmain() void { const msg = std.fmt.allocPrint(alloc, "Hello {}!", .{"ziguser"}); std.log.debug("message: {}", .{msg}); + // var cr3: usize = asm volatile ( + // "mov %%cr3, %%rax" : [cr3] "={rax}" (-> usize) :: + // ); + // std.log.info("cr3 = {x}", .{cr3}); + + // const page_lvl4 = @intToPtr(*[512]u64, cr3); + + // arch.paging.showTable(page_lvl4.*); + // time.displayTime(debug.AWriter) catch unreachable; const cmdline = std.mem.span(c.boot_info.cmdline); std.log.info("cmdline: {}", .{cmdline}); + // std.log.info("pagefault/protectionfault time: {}", .{@intToPtr([*:0]u8, 0xcfffffff80000000)}); // @panic("ee");