import arch-specific stuff in kernel-main

This commit is contained in:
Quinten Kock 2020-12-26 02:18:32 +01:00
parent b34cb5f8b4
commit d7e2df626d
10 changed files with 131 additions and 22 deletions

View File

View File

@ -1,2 +1 @@
extern char archval;
const char *arch = &archval;
const char *arch = "i386";

View File

@ -1,3 +0,0 @@
.global archval
archval:
.asciz "i386-gas"

View File

View File

@ -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");

View File

@ -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));
}
}

View File

@ -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);
}

View File

@ -14,4 +14,3 @@
call panic
%endmacro
%endif

View File

@ -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;
}

View File

@ -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");