PIT configured, preparing for scheduling
This commit is contained in:
parent
bd12f0495f
commit
902aa136c6
10 changed files with 112 additions and 47 deletions
|
|
@ -50,8 +50,14 @@ pub fn setGate(n: u8, flags: u8, offset: extern fn () void) void {
|
||||||
|
|
||||||
// Initialize the Interrupt Descriptor Table.
|
// Initialize the Interrupt Descriptor Table.
|
||||||
pub fn initialize() void {
|
pub fn initialize() void {
|
||||||
// configure PIC and set ISRs
|
// configure PIC
|
||||||
interrupt.initialize();
|
interrupt.remapPIC();
|
||||||
|
interrupt.configPIT();
|
||||||
|
// install ISRs
|
||||||
|
isr.install_exceptions();
|
||||||
|
isr.install_irqs();
|
||||||
|
isr.install_syscalls();
|
||||||
|
interrupt.registerIRQ(0, interrupt.pit_handler);
|
||||||
|
|
||||||
// load IDT
|
// load IDT
|
||||||
lidt(@ptrToInt(&idtr));
|
lidt(@ptrToInt(&idtr));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
pub usingnamespace @import("../../vga.zig");
|
pub usingnamespace @import("../../vga.zig");
|
||||||
pub const multiboot = @import("../../multiboot.zig");
|
pub const multiboot = @import("../../multiboot.zig");
|
||||||
|
pub const time = @import("../../time.zig");
|
||||||
|
|
||||||
pub usingnamespace @import("lib/io.zig");
|
pub usingnamespace @import("lib/io.zig");
|
||||||
pub usingnamespace @import("lib/instructions.zig");
|
pub usingnamespace @import("lib/instructions.zig");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
usingnamespace @import("index.zig");
|
usingnamespace @import("index.zig");
|
||||||
// const x86 = @import("index.zig");
|
|
||||||
// const isr = @import("isr.zig");
|
|
||||||
|
|
||||||
// PIC ports.
|
// PIC ports.
|
||||||
const PIC1_CMD = 0x20;
|
const PIC1_CMD = 0x20;
|
||||||
|
|
@ -16,6 +14,11 @@ const ICW1_ICW4 = 0x01;
|
||||||
const ICW4_8086 = 0x01;
|
const ICW4_8086 = 0x01;
|
||||||
// write 0 to wait
|
// write 0 to wait
|
||||||
const WAIT_PORT = 0x80;
|
const WAIT_PORT = 0x80;
|
||||||
|
// PIT Channels
|
||||||
|
const PIT_CHAN0 = 0x40;
|
||||||
|
const PIT_CHAN1 = 0x41;
|
||||||
|
const PIT_CHAN2 = 0x42;
|
||||||
|
const PIT_CMD = 0x43;
|
||||||
// Interrupt Vector offsets of exceptions.
|
// Interrupt Vector offsets of exceptions.
|
||||||
const EXCEPTION_0 = 0;
|
const EXCEPTION_0 = 0;
|
||||||
const EXCEPTION_31 = EXCEPTION_0 + 31;
|
const EXCEPTION_31 = EXCEPTION_0 + 31;
|
||||||
|
|
@ -132,7 +135,7 @@ pub fn registerIRQ(irq: u8, handler: fn () void) void {
|
||||||
maskIRQ(irq, false); // Unmask the IRQ.
|
maskIRQ(irq, false); // Unmask the IRQ.
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remapPIC() void {
|
pub fn remapPIC() void {
|
||||||
// ICW1: start initialization sequence.
|
// ICW1: start initialization sequence.
|
||||||
outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
|
outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
|
||||||
picwait();
|
picwait();
|
||||||
|
|
@ -180,10 +183,21 @@ pub fn maskIRQ(irq: u8, mask: bool) void {
|
||||||
const new = inb(port); // Retrieve the current mask.
|
const new = inb(port); // Retrieve the current mask.
|
||||||
}
|
}
|
||||||
|
|
||||||
////
|
// configures the chan0 with a rate generator, which will trigger irq0
|
||||||
// Initialize interrupts.
|
pub fn configPIT() void {
|
||||||
//
|
const chanNum = 0;
|
||||||
pub fn initialize() void {
|
const chan = PIT_CHAN0;
|
||||||
remapPIC();
|
const divisor = 2685;
|
||||||
isr.install();
|
const LOHI = 0b11; // bit4 | bit5
|
||||||
|
const PITMODE_RATE_GEN = 0x2;
|
||||||
|
outb(PIT_CMD, chanNum << 6 | LOHI << 4 | PITMODE_RATE_GEN << 1);
|
||||||
|
outb(PIT_CHAN0, divisor & 0xff);
|
||||||
|
outb(PIT_CHAN0, divisor >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pit_handler() void {
|
||||||
|
// pit freq = 1.193182 MHz
|
||||||
|
// chan0 divisor = 2685
|
||||||
|
// PIT_RATE in us
|
||||||
|
time.increment(2251);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,8 @@ pub export var context: *volatile Context = undefined;
|
||||||
////
|
////
|
||||||
// Install the Interrupt Service Routines in the IDT.
|
// Install the Interrupt Service Routines in the IDT.
|
||||||
//
|
//
|
||||||
pub fn install() void {
|
pub fn install_exceptions() void {
|
||||||
// Exceptions.
|
// Exceptions.
|
||||||
idt.setGate(0, idt.INTERRUPT_GATE, isr0);
|
|
||||||
idt.setGate(1, idt.INTERRUPT_GATE, isr1);
|
idt.setGate(1, idt.INTERRUPT_GATE, isr1);
|
||||||
idt.setGate(2, idt.INTERRUPT_GATE, isr2);
|
idt.setGate(2, idt.INTERRUPT_GATE, isr2);
|
||||||
idt.setGate(3, idt.INTERRUPT_GATE, isr3);
|
idt.setGate(3, idt.INTERRUPT_GATE, isr3);
|
||||||
|
|
@ -121,8 +120,10 @@ pub fn install() void {
|
||||||
idt.setGate(29, idt.INTERRUPT_GATE, isr29);
|
idt.setGate(29, idt.INTERRUPT_GATE, isr29);
|
||||||
idt.setGate(30, idt.INTERRUPT_GATE, isr30);
|
idt.setGate(30, idt.INTERRUPT_GATE, isr30);
|
||||||
idt.setGate(31, idt.INTERRUPT_GATE, isr31);
|
idt.setGate(31, idt.INTERRUPT_GATE, isr31);
|
||||||
|
}
|
||||||
|
|
||||||
// IRQs.
|
// IRQs.
|
||||||
|
pub fn install_irqs() void {
|
||||||
idt.setGate(32, idt.INTERRUPT_GATE, isr32);
|
idt.setGate(32, idt.INTERRUPT_GATE, isr32);
|
||||||
idt.setGate(33, idt.INTERRUPT_GATE, isr33);
|
idt.setGate(33, idt.INTERRUPT_GATE, isr33);
|
||||||
idt.setGate(34, idt.INTERRUPT_GATE, isr34);
|
idt.setGate(34, idt.INTERRUPT_GATE, isr34);
|
||||||
|
|
@ -139,7 +140,9 @@ pub fn install() void {
|
||||||
idt.setGate(45, idt.INTERRUPT_GATE, isr45);
|
idt.setGate(45, idt.INTERRUPT_GATE, isr45);
|
||||||
idt.setGate(46, idt.INTERRUPT_GATE, isr46);
|
idt.setGate(46, idt.INTERRUPT_GATE, isr46);
|
||||||
idt.setGate(47, idt.INTERRUPT_GATE, isr47);
|
idt.setGate(47, idt.INTERRUPT_GATE, isr47);
|
||||||
|
}
|
||||||
|
|
||||||
// Syscalls.
|
// Syscalls.
|
||||||
|
pub fn install_syscalls() void {
|
||||||
idt.setGate(128, idt.SYSCALL_GATE, isr128);
|
idt.setGate(128, idt.SYSCALL_GATE, isr128);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ var command_len: usize = 0;
|
||||||
fn execute(com: []u8) void {
|
fn execute(com: []u8) void {
|
||||||
if (@import("std").mem.eql(u8, com, "lspci")) pci.lspci();
|
if (@import("std").mem.eql(u8, com, "lspci")) pci.lspci();
|
||||||
if (@import("std").mem.eql(u8, com, "paging")) x86.paging.addrspace();
|
if (@import("std").mem.eql(u8, com, "paging")) x86.paging.addrspace();
|
||||||
|
if (@import("std").mem.eql(u8, com, "uptime")) time.uptime();
|
||||||
|
if (@import("std").mem.eql(u8, com, "topbar")) topbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keypress(char: u8) void {
|
pub fn keypress(char: u8) void {
|
||||||
|
|
@ -17,8 +19,14 @@ pub fn keypress(char: u8) void {
|
||||||
print("> ");
|
print("> ");
|
||||||
command_len = 0;
|
command_len = 0;
|
||||||
},
|
},
|
||||||
'\x08' => return, //backspace
|
|
||||||
'\x00' => return,
|
'\x00' => return,
|
||||||
|
'\x08' => {
|
||||||
|
// backspace
|
||||||
|
if (command_len == 0) return;
|
||||||
|
vga.writeChar(char);
|
||||||
|
command_len -= 1;
|
||||||
|
command[command_len] = '\x00';
|
||||||
|
},
|
||||||
else => {
|
else => {
|
||||||
// general case
|
// general case
|
||||||
if (command_len == 10) return;
|
if (command_len == 10) return;
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,4 @@ pub const console = @import("console.zig");
|
||||||
pub const pci = @import("pci/pci.zig");
|
pub const pci = @import("pci/pci.zig");
|
||||||
pub const ps2 = @import("ps2.zig");
|
pub const ps2 = @import("ps2.zig");
|
||||||
pub const x86 = @import("arch/x86/index.zig");
|
pub const x86 = @import("arch/x86/index.zig");
|
||||||
|
pub const time = @import("time.zig");
|
||||||
|
|
|
||||||
21
src/main.zig
21
src/main.zig
|
|
@ -16,27 +16,6 @@ export const multiboot_header align(4) linksection(".multiboot") = multiboot: {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// export var stack_bytes: [16 * 1024]u8 align(16) linksection(".bss") = undefined;
|
|
||||||
// const stack_bytes_slice = stack_bytes[0..];
|
|
||||||
|
|
||||||
// linker.ld entrypoint
|
|
||||||
// export nakedcc fn __start() noreturn {
|
|
||||||
// // eax -> multiboot magic
|
|
||||||
// // ebx -> multiboot info
|
|
||||||
// const magic = asm volatile ("mov %[ret], %eax"
|
|
||||||
// : [ret] "=" (-> u32)
|
|
||||||
// );
|
|
||||||
// const info = asm volatile (""
|
|
||||||
// : [ret] "=" (-> u32)
|
|
||||||
// );
|
|
||||||
// clear();
|
|
||||||
// println("--- {x} ---", magic);
|
|
||||||
// println("--- {x} ---", info);
|
|
||||||
// // @newStackCall(stack_bytes_slice, kmain, magic, @intToPtr(*const multiboot.MultibootInfo, info));
|
|
||||||
// @newStackCall(stack_bytes_slice, kmain, magic);
|
|
||||||
// // @newStackCall(stack_bytes_slice, kmain);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// arch independant initialization
|
// arch independant initialization
|
||||||
export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
||||||
assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);
|
assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,37 @@ pub fn init(dev: PciDevice) void {
|
||||||
const max_lat = dev.config_read(u8, 0x3f);
|
const max_lat = dev.config_read(u8, 0x3f);
|
||||||
println("{x} {} {} {}", intr_line, intr_pin, min_grant, max_lat);
|
println("{x} {} {} {}", intr_line, intr_pin, min_grant, max_lat);
|
||||||
|
|
||||||
println("dev features =0x{x}", dev.config_read(u32, 0x10));
|
// all virtio
|
||||||
println("guest features=0x{x}", dev.config_read(u32, 0x14));
|
// 0 1 2 3
|
||||||
println("queue addr =0x{x}", dev.config_read(u32, 0x18));
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
println("queue size =0x{x}", dev.config_read(u16, 0x1c));
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
println("queue select =0x{x}", dev.config_read(u16, 0x1e));
|
// | dev features |
|
||||||
println("queue notify =0x{x}", dev.config_read(u16, 0x20));
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
println("device status =0x{x}", dev.config_read(u8, 0x22));
|
// | guest features |
|
||||||
println("isr status =0x{x}", dev.config_read(u8, 0x23));
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | queue address |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | queue size | queue notify |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | device status | isr status |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
// println("dev feats =0x{x}", dev.config_read(u32, 0x10));
|
||||||
|
// println("guest feats =0x{x}", dev.config_read(u32, 0x14));
|
||||||
|
// println("queue addr =0x{x}", dev.config_read(u32, 0x18));
|
||||||
|
// println("queue size =0x{x}", dev.config_read(u16, 0x1c));
|
||||||
|
// println("queue select =0x{x}", dev.config_read(u16, 0x1e));
|
||||||
|
// println("queue notify =0x{x}", dev.config_read(u16, 0x20));
|
||||||
|
// println("device status=0x{x}", dev.config_read(u8, 0x22));
|
||||||
|
// println("isr status =0x{x}", dev.config_read(u8, 0x23));
|
||||||
|
|
||||||
|
// all virtio-block
|
||||||
|
// println("Total Sector Count={}", dev.config_read(u32, 0x24));
|
||||||
|
// println("Total Sector Count={}", dev.config_read(u32, 0x28));
|
||||||
|
// println("Maximum Seg Size ={}", dev.config_read(u16, 0x2c));
|
||||||
|
// println("Maximum Seg Count ={}", dev.config_read(u32, 0x30));
|
||||||
|
// println("Cylinder Count ={}", dev.config_read(u16, 0x34));
|
||||||
|
// println("Head Count ={}", dev.config_read(u8, 0x36));
|
||||||
|
// println("Sector Count ={}", dev.config_read(u8, 0x37));
|
||||||
|
// println("Block Length ={}", dev.config_read(u8, 0x38));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
src/time.zig
Normal file
14
src/time.zig
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
usingnamespace @import("index.zig");
|
||||||
|
|
||||||
|
pub var offset_s: u32 = 0;
|
||||||
|
pub var offset_us: u32 = 0;
|
||||||
|
pub fn increment(value: u32) void {
|
||||||
|
const sum = offset_us + value;
|
||||||
|
offset_s += sum / 1000000;
|
||||||
|
offset_us = sum % 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uptime() void {
|
||||||
|
const offset_ms = offset_us / 1000;
|
||||||
|
println("uptime: {}.{:.3}", offset_s, offset_ms);
|
||||||
|
}
|
||||||
18
src/vga.zig
18
src/vga.zig
|
|
@ -1,3 +1,5 @@
|
||||||
|
// usingnamespace @import("index.zig");
|
||||||
|
const time = @import("time.zig");
|
||||||
const x86 = @import("arch/x86/index.zig");
|
const x86 = @import("arch/x86/index.zig");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
|
@ -7,7 +9,7 @@ pub const VGA_HEIGHT = 25;
|
||||||
pub const VGA_SIZE = VGA_WIDTH * VGA_HEIGHT;
|
pub const VGA_SIZE = VGA_WIDTH * VGA_HEIGHT;
|
||||||
pub var vga = VGA{
|
pub var vga = VGA{
|
||||||
.vram = @intToPtr([*]VGAEntry, 0xb8000)[0..0x4000],
|
.vram = @intToPtr([*]VGAEntry, 0xb8000)[0..0x4000],
|
||||||
.cursor = 0,
|
.cursor = 80 * 2,
|
||||||
.foreground = Color.Black,
|
.foreground = Color.Black,
|
||||||
.background = Color.Brown,
|
.background = Color.Brown,
|
||||||
};
|
};
|
||||||
|
|
@ -62,6 +64,18 @@ pub fn println(comptime format: []const u8, args: ...) void {
|
||||||
pub fn clear() void {
|
pub fn clear() void {
|
||||||
vga.clear();
|
vga.clear();
|
||||||
}
|
}
|
||||||
|
pub fn topbar() void {
|
||||||
|
const cursor = vga.cursor;
|
||||||
|
const bg = vga.background;
|
||||||
|
vga.cursor = 0;
|
||||||
|
vga.background = Color.Red;
|
||||||
|
|
||||||
|
const offset_ms = time.offset_us / 1000;
|
||||||
|
println("{}.{}", time.offset_s, offset_ms / 10);
|
||||||
|
|
||||||
|
vga.cursor = cursor;
|
||||||
|
vga.background = bg;
|
||||||
|
}
|
||||||
|
|
||||||
fn printCallback(context: void, string: []const u8) Errors!void {
|
fn printCallback(context: void, string: []const u8) Errors!void {
|
||||||
vga.writeString(string);
|
vga.writeString(string);
|
||||||
|
|
@ -79,7 +93,7 @@ const VGA = struct {
|
||||||
pub fn clear(self: *VGA) void {
|
pub fn clear(self: *VGA) void {
|
||||||
std.mem.set(VGAEntry, self.vram[0..VGA_SIZE], self.entry(' '));
|
std.mem.set(VGAEntry, self.vram[0..VGA_SIZE], self.entry(' '));
|
||||||
|
|
||||||
self.cursor = 0;
|
self.cursor = 80; // skip 1 line for topbar
|
||||||
self.updateCursor();
|
self.updateCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue