aboutsummaryrefslogtreecommitdiff
path: root/mirai/boot/tss/tss.zig
blob: 395ef06230405cc67cf249a161dfce011d2ab5a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//! Task State Segment

const boot_limits = @import("../../common/limits/boot.zig");
const serial = @import("../../drivers/serial/serial.zig");

const TSS = packed struct {
    reserved1: u32,
    rsp0: u64,
    rsp1: u64,
    rsp2: u64,
    reserved2: u64,
    ist1: u64,
    ist2: u64,
    ist3: u64,
    ist4: u64,
    ist5: u64,
    ist6: u64,
    ist7: u64,
    reserved3: u64,
    reserved4: u16,
    iomap_base: u16,
};

var tss: TSS align(16) = undefined;
var kernel_stack: [boot_limits.KERNEL_STACK_SIZE]u8 align(16) = undefined;
var ist1_stack: [65536]u8 align(16) = undefined; // 64KB for double fault/page fault

pub fn init() void {
    const tss_bytes = @as([*]u8, @ptrCast(&tss));
    for (0..@sizeOf(TSS)) |i| {
        tss_bytes[i] = 0;
    }

    tss.rsp0 = @intFromPtr(&kernel_stack) + kernel_stack.len;
    tss.ist1 = @intFromPtr(&ist1_stack) + ist1_stack.len;

    serial.printf("TSS: addr={x} rsp0={x} ist1={x}\n", .{ @intFromPtr(&tss), tss.rsp0, tss.ist1 });
}

pub fn get_address() u64 {
    return @intFromPtr(&tss);
}

pub fn get_size() u64 {
    return @sizeOf(TSS) - 1;
}

pub fn set_kernel_stack(stack_pointer: u64) void {
    tss.rsp0 = stack_pointer;
}

pub fn get_kernel_stack() u64 {
    return tss.rsp0;
}