Update to zig master and simplify build script

This commit is contained in:
Andrew Kelley 2019-09-03 14:13:26 -04:00 committed by Sam Tebbs
parent b2ce5f6310
commit 798b1c1d34
9 changed files with 143 additions and 636 deletions

View file

@ -9,58 +9,56 @@ const TABLE_SIZE: u16 = @sizeOf(GdtEntry) * NUMBER_OF_ENTRIES - 1;
// The indexes into the GDT where each segment resides.
/// The index of the NULL GDT entry.
const NULL_INDEX: u16 = 0x00;
const NULL_INDEX: u16 = 0x00;
/// The index of the kernel code GDT entry.
const KERNEL_CODE_INDEX: u16 = 0x01;
const KERNEL_CODE_INDEX: u16 = 0x01;
/// The index of the kernel data GDT entry.
const KERNEL_DATA_INDEX: u16 = 0x02;
const KERNEL_DATA_INDEX: u16 = 0x02;
/// The index of the user code GDT entry.
const USER_CODE_INDEX: u16 = 0x03;
const USER_CODE_INDEX: u16 = 0x03;
/// The index of the user data GDT entry.
const USER_DATA_INDEX: u16 = 0x04;
const USER_DATA_INDEX: u16 = 0x04;
/// The index of the task state segment GDT entry.
const TSS_INDEX: u16 = 0x05;
const TSS_INDEX: u16 = 0x05;
// The offsets into the GDT where each segment resides.
/// The offset of the NULL GDT entry.
pub const NULL_OFFSET: u16 = 0x00;
pub const NULL_OFFSET: u16 = 0x00;
/// The offset of the kernel code GDT entry.
pub const KERNEL_CODE_OFFSET: u16 = 0x08;
pub const KERNEL_CODE_OFFSET: u16 = 0x08;
/// The offset of the kernel data GDT entry.
pub const KERNEL_DATA_OFFSET: u16 = 0x10;
pub const KERNEL_DATA_OFFSET: u16 = 0x10;
/// The offset of the user code GDT entry.
pub const USER_CODE_OFFSET: u16 = 0x18;
pub const USER_CODE_OFFSET: u16 = 0x18;
/// The offset of the user data GDT entry.
pub const USER_DATA_OFFSET: u16 = 0x20;
pub const USER_DATA_OFFSET: u16 = 0x20;
/// The offset of the TTS GDT entry.
pub const TSS_OFFSET: u16 = 0x28;
pub const TSS_OFFSET: u16 = 0x28;
// The access bits
const ACCESSED_BIT = 0x01; // 00000001
const WRITABLE_BIT = 0x02; // 00000010
const DIRECTION_CONFORMING_BIT = 0x04; // 00000100
const EXECUTABLE_BIT = 0x08; // 00001000
const DESCRIPTOR_BIT = 0x10; // 00010000
const ACCESSED_BIT = 0x01; // 00000001
const WRITABLE_BIT = 0x02; // 00000010
const DIRECTION_CONFORMING_BIT = 0x04; // 00000100
const EXECUTABLE_BIT = 0x08; // 00001000
const DESCRIPTOR_BIT = 0x10; // 00010000
const PRIVILEGE_RING_0 = 0x00; // 00000000
const PRIVILEGE_RING_1 = 0x20; // 00100000
const PRIVILEGE_RING_2 = 0x40; // 01000000
const PRIVILEGE_RING_3 = 0x60; // 01100000
const PRESENT_BIT = 0x80; // 10000000
const PRIVILEGE_RING_0 = 0x00; // 00000000
const PRIVILEGE_RING_1 = 0x20; // 00100000
const PRIVILEGE_RING_2 = 0x40; // 01000000
const PRIVILEGE_RING_3 = 0x60; // 01100000
const PRESENT_BIT = 0x80; // 10000000
const KERNEL_SEGMENT = PRESENT_BIT | PRIVILEGE_RING_0 | DESCRIPTOR_BIT;
const USER_SEGMENT = PRESENT_BIT | PRIVILEGE_RING_3 | DESCRIPTOR_BIT;
@ -70,11 +68,10 @@ const DATA_SEGMENT = WRITABLE_BIT;
const TSS_SEGMENT = PRESENT_BIT | EXECUTABLE_BIT | ACCESSED_BIT;
// The flag bits
const IS_64_BIT = 0x02; // 0010
const IS_32_BIT = 0x04; // 0100
const IS_LIMIT_4K_BIT = 0x08; // 1000
const IS_64_BIT = 0x02; // 0010
const IS_32_BIT = 0x04; // 0100
const IS_LIMIT_4K_BIT = 0x08; // 1000
/// The structure that contains all the information that each GDT entry needs.
const GdtEntry = packed struct {
@ -213,7 +210,7 @@ const TtsEntry = packed struct {
/// A new GDT entry with the give access and flag bits set with the base at 0x00000000 and limit at 0xFFFFF.
///
fn makeEntry(base: u32, limit: u20, access: u8, flags: u4) GdtEntry {
return GdtEntry {
return GdtEntry{
.limit_low = @truncate(u16, limit),
.base_low = @truncate(u24, base),
.access = access,
@ -224,7 +221,7 @@ fn makeEntry(base: u32, limit: u20, access: u8, flags: u4) GdtEntry {
}
/// The GDT entry table of NUMBER_OF_ENTRIES entries.
var gdt_entries: [NUMBER_OF_ENTRIES]GdtEntry = []GdtEntry {
var gdt_entries: [NUMBER_OF_ENTRIES]GdtEntry = [_]GdtEntry{
// Null descriptor
makeEntry(0, 0, 0, 0),
@ -246,13 +243,13 @@ var gdt_entries: [NUMBER_OF_ENTRIES]GdtEntry = []GdtEntry {
/// The GDT pointer that the CPU is loaded with that contains the base address of the GDT and the
/// size.
const gdt_ptr: GdtPtr = GdtPtr {
const gdt_ptr: GdtPtr = GdtPtr{
.limit = TABLE_SIZE,
.base = &gdt_entries[0],
};
/// The task state segment entry.
var tss: TtsEntry = TtsEntry {
var tss: TtsEntry = TtsEntry{
.prev_tss = 0,
.esp0 = undefined,
.ss0 = KERNEL_DATA_OFFSET,

View file

@ -58,11 +58,11 @@ pub const IdtPtr = packed struct {
};
/// The IDT entry table of NUMBER_OF_ENTRIES entries.
var idt: [NUMBER_OF_ENTRIES]IdtEntry = []IdtEntry{makeEntry(0, 0, 0, 0, 0)} ** NUMBER_OF_ENTRIES;
var idt: [NUMBER_OF_ENTRIES]IdtEntry = [_]IdtEntry{makeEntry(0, 0, 0, 0, 0)} ** NUMBER_OF_ENTRIES;
/// The IDT pointer that the CPU is loaded with that contains the base address of the IDT and the
/// size.
const idt_ptr: IdtPtr = IdtPtr {
const idt_ptr: IdtPtr = IdtPtr{
.limit = TABLE_SIZE,
.base = &idt[0],
};
@ -83,7 +83,7 @@ const idt_ptr: IdtPtr = IdtPtr {
/// A new IDT entry.
///
fn makeEntry(base: u32, selector: u16, gate_type: u4, privilege: u2, present: u1) IdtEntry {
return IdtEntry {
return IdtEntry{
.base_low = @truncate(u16, base),
.selector = selector,
.zero = 0,
@ -102,7 +102,7 @@ fn makeEntry(base: u32, selector: u16, gate_type: u4, privilege: u2, present: u1
/// IN index: u8 - The interrupt number to close.
/// IN base: extern fn()void - The function handler for the interrupt.
///
pub fn openInterruptGate(index: u8, base: extern fn()void) void {
pub fn openInterruptGate(index: u8, base: extern fn () void) void {
idt[index] = makeEntry(@ptrToInt(base), gdt.KERNEL_CODE_OFFSET, INTERRUPT_GATE_32BIT, PRIVILEGE_RING_0, 1);
}

View file

@ -28,7 +28,7 @@ extern fn irq14() void;
extern fn irq15() void;
/// The list of IRQ handlers initialised to unhandled.
var irq_handlers: [NUMBER_OF_ENTRIES]fn(*arch.InterruptContext)void = []fn(*arch.InterruptContext)void {unhandled} ** NUMBER_OF_ENTRIES;
var irq_handlers: [NUMBER_OF_ENTRIES]fn (*arch.InterruptContext) void = [_]fn (*arch.InterruptContext) void{unhandled} ** NUMBER_OF_ENTRIES;
///
/// A dummy handler that will make a call to panic as it is a unhandled interrupt.
@ -66,7 +66,7 @@ export fn irqHandler(context: *arch.InterruptContext) void {
/// Arguments:
/// IN irq_num: u16 - The IRQ number to register.
///
pub fn registerIrq(irq_num: u16, handler: fn(*arch.InterruptContext)void) void {
pub fn registerIrq(irq_num: u16, handler: fn (*arch.InterruptContext) void) void {
irq_handlers[irq_num] = handler;
pic.clearMask(irq_num);
}
@ -108,4 +108,4 @@ pub fn init() void {
idt.openInterruptGate(45, irq13);
idt.openInterruptGate(46, irq14);
idt.openInterruptGate(47, irq15);
}
}

View file

@ -43,7 +43,7 @@ extern fn isr31() void;
extern fn isr128() void;
/// The exception messaged that is printed when a exception happens
const exception_msg: [NUMBER_OF_ENTRIES][]const u8 = [NUMBER_OF_ENTRIES][]const u8 {
const exception_msg: [NUMBER_OF_ENTRIES][]const u8 = [NUMBER_OF_ENTRIES][]const u8{
"Divide By Zero",
"Single Step (Debugger)",
"Non Maskable Interrupt",
@ -75,20 +75,18 @@ const exception_msg: [NUMBER_OF_ENTRIES][]const u8 = [NUMBER_OF_ENTRIES][]const
"Reserved",
"Reserved",
"Security",
"Reserved"
"Reserved",
};
/// Errors that an isr function can return
pub const IsrError = error {
UnrecognisedIsr
};
pub const IsrError = error{UnrecognisedIsr};
/// An isr handler. Takes an interrupt context and returns void.
/// Should finish quickly to avoid delaying further interrupts and the previously running code
pub const IsrHandler = fn(*arch.InterruptContext)void;
pub const IsrHandler = fn (*arch.InterruptContext) void;
// The of exception handlers initialised to unhandled.
var isr_handlers: [NUMBER_OF_ENTRIES]IsrHandler = []IsrHandler{unhandled} ** NUMBER_OF_ENTRIES;
var isr_handlers: [NUMBER_OF_ENTRIES]IsrHandler = [_]IsrHandler{unhandled} ** NUMBER_OF_ENTRIES;
var syscall_handler: IsrHandler = unhandled;
///
@ -141,7 +139,7 @@ export fn isrHandler(context: *arch.InterruptContext) void {
/// Errors:
/// IsrError.UnrecognisedIsr - If `isr_num` is invalid (see isValidIsr)
///
pub fn registerIsr(isr_num: u16, handler: fn(*arch.InterruptContext)void) !void {
pub fn registerIsr(isr_num: u16, handler: fn (*arch.InterruptContext) void) !void {
if (isr_num == syscalls.INTERRUPT) {
syscall_handler = handler;
} else if (isValidIsr(isr_num)) {

View file

@ -14,13 +14,13 @@ pub const NUM_HANDLERS: u16 = 256;
pub const SyscallHandler = fn (ctx: *arch.InterruptContext) u32;
/// Errors that syscall utility functions can throw
pub const SyscallError = error {
pub const SyscallError = error{
SyscallExists,
InvalidSyscall
InvalidSyscall,
};
/// The array of registered syscalls
var handlers: [NUM_HANDLERS]?SyscallHandler = []?SyscallHandler{null} ** NUM_HANDLERS;
var handlers: [NUM_HANDLERS]?SyscallHandler = [_]?SyscallHandler{null} ** NUM_HANDLERS;
///
/// Returns true if the syscall is valid, else false.
@ -84,7 +84,7 @@ inline fn syscall0(syscall: u32) u32 {
return asm volatile (
\\int $0x80
: [ret] "={eax}" (-> u32)
: [syscall] "{eax}" (syscall),
: [syscall] "{eax}" (syscall)
);
}
@ -100,7 +100,7 @@ inline fn syscall1(syscall: u32, arg: u32) u32 {
\\int $0x80
: [ret] "={eax}" (-> u32)
: [syscall] "{eax}" (syscall),
[arg1] "{ebx}" (arg),
[arg1] "{ebx}" (arg)
);
}
@ -118,7 +118,7 @@ inline fn syscall2(syscall: u32, arg1: u32, arg2: u32) u32 {
: [ret] "={eax}" (-> u32)
: [syscall] "{eax}" (syscall),
[arg1] "{ebx}" (arg1),
[arg2] "{ecx}" (arg2),
[arg2] "{ecx}" (arg2)
);
}
@ -138,7 +138,7 @@ inline fn syscall3(syscall: u32, arg1: u32, arg2: u32, arg3: u32) u32 {
: [syscall] "{eax}" (syscall),
[arg1] "{ebx}" (arg1),
[arg2] "{ecx}" (arg2),
[arg3] "{edx}" (arg3),
[arg3] "{edx}" (arg3)
);
}
@ -160,7 +160,7 @@ inline fn syscall4(syscall: u32, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32
[arg1] "{ebx}" (arg1),
[arg2] "{ecx}" (arg2),
[arg3] "{edx}" (arg3),
[arg4] "{esi}" (arg4),
[arg4] "{esi}" (arg4)
);
}
@ -184,7 +184,7 @@ inline fn syscall5(syscall: u32, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg
[arg2] "{ecx}" (arg2),
[arg3] "{edx}" (arg3),
[arg4] "{esi}" (arg4),
[arg5] "{edi}" (arg5),
[arg5] "{edi}" (arg5)
);
}
@ -202,7 +202,7 @@ inline fn syscallArg(ctx: *arch.InterruptContext, comptime arg_idx: u32) u32 {
2 => ctx.edx,
3 => ctx.esi,
4 => ctx.edi,
else => @compileError("Arg index must be between 0 and 4")
else => @compileError("Arg index must be between 0 and 4"),
};
}
@ -217,7 +217,6 @@ pub fn init(comptime options: type) void {
}
/// Tests
var testInt: u32 = 0;
fn testHandler0(ctx: *arch.InterruptContext) u32 {

View file

@ -11,6 +11,13 @@ const serial = @import("serial.zig");
const mem = @import("mem.zig");
const options = @import("build_options");
comptime {
switch (builtin.arch) {
.i386 => _ = @import("arch/x86/boot.zig"),
else => {},
}
}
// Need to import this as we need the panic to be in the root source file, or zig will just use the
// builtin panic and just loop, which is what we don't want
const panic_root = @import("panic.zig");

File diff suppressed because it is too large Load diff