PIT configured, preparing for scheduling

This commit is contained in:
Jack Halford 2019-09-14 15:49:57 +02:00
parent bd12f0495f
commit 902aa136c6
10 changed files with 112 additions and 47 deletions

View file

@ -50,8 +50,14 @@ pub fn setGate(n: u8, flags: u8, offset: extern fn () void) void {
// Initialize the Interrupt Descriptor Table.
pub fn initialize() void {
// configure PIC and set ISRs
interrupt.initialize();
// configure PIC
interrupt.remapPIC();
interrupt.configPIT();
// install ISRs
isr.install_exceptions();
isr.install_irqs();
isr.install_syscalls();
interrupt.registerIRQ(0, interrupt.pit_handler);
// load IDT
lidt(@ptrToInt(&idtr));

View file

@ -1,5 +1,6 @@
pub usingnamespace @import("../../vga.zig");
pub const multiboot = @import("../../multiboot.zig");
pub const time = @import("../../time.zig");
pub usingnamespace @import("lib/io.zig");
pub usingnamespace @import("lib/instructions.zig");

View file

@ -1,6 +1,4 @@
usingnamespace @import("index.zig");
// const x86 = @import("index.zig");
// const isr = @import("isr.zig");
// PIC ports.
const PIC1_CMD = 0x20;
@ -16,6 +14,11 @@ const ICW1_ICW4 = 0x01;
const ICW4_8086 = 0x01;
// write 0 to wait
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.
const EXCEPTION_0 = 0;
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.
}
fn remapPIC() void {
pub fn remapPIC() void {
// ICW1: start initialization sequence.
outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
picwait();
@ -180,10 +183,21 @@ pub fn maskIRQ(irq: u8, mask: bool) void {
const new = inb(port); // Retrieve the current mask.
}
////
// Initialize interrupts.
//
pub fn initialize() void {
remapPIC();
isr.install();
// configures the chan0 with a rate generator, which will trigger irq0
pub fn configPIT() void {
const chanNum = 0;
const chan = PIT_CHAN0;
const divisor = 2685;
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);
}

View file

@ -87,9 +87,8 @@ pub export var context: *volatile Context = undefined;
////
// Install the Interrupt Service Routines in the IDT.
//
pub fn install() void {
pub fn install_exceptions() void {
// Exceptions.
idt.setGate(0, idt.INTERRUPT_GATE, isr0);
idt.setGate(1, idt.INTERRUPT_GATE, isr1);
idt.setGate(2, idt.INTERRUPT_GATE, isr2);
idt.setGate(3, idt.INTERRUPT_GATE, isr3);
@ -121,8 +120,10 @@ pub fn install() void {
idt.setGate(29, idt.INTERRUPT_GATE, isr29);
idt.setGate(30, idt.INTERRUPT_GATE, isr30);
idt.setGate(31, idt.INTERRUPT_GATE, isr31);
}
// IRQs.
pub fn install_irqs() void {
idt.setGate(32, idt.INTERRUPT_GATE, isr32);
idt.setGate(33, idt.INTERRUPT_GATE, isr33);
idt.setGate(34, idt.INTERRUPT_GATE, isr34);
@ -139,7 +140,9 @@ pub fn install() void {
idt.setGate(45, idt.INTERRUPT_GATE, isr45);
idt.setGate(46, idt.INTERRUPT_GATE, isr46);
idt.setGate(47, idt.INTERRUPT_GATE, isr47);
}
// Syscalls.
pub fn install_syscalls() void {
idt.setGate(128, idt.SYSCALL_GATE, isr128);
}

View file

@ -6,6 +6,8 @@ var command_len: usize = 0;
fn execute(com: []u8) void {
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, "uptime")) time.uptime();
if (@import("std").mem.eql(u8, com, "topbar")) topbar();
}
pub fn keypress(char: u8) void {
@ -17,8 +19,14 @@ pub fn keypress(char: u8) void {
print("> ");
command_len = 0;
},
'\x08' => return, //backspace
'\x00' => return,
'\x08' => {
// backspace
if (command_len == 0) return;
vga.writeChar(char);
command_len -= 1;
command[command_len] = '\x00';
},
else => {
// general case
if (command_len == 10) return;

View file

@ -7,3 +7,4 @@ pub const console = @import("console.zig");
pub const pci = @import("pci/pci.zig");
pub const ps2 = @import("ps2.zig");
pub const x86 = @import("arch/x86/index.zig");
pub const time = @import("time.zig");

View file

@ -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
export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);

View file

@ -12,12 +12,37 @@ pub fn init(dev: PciDevice) void {
const max_lat = dev.config_read(u8, 0x3f);
println("{x} {} {} {}", intr_line, intr_pin, min_grant, max_lat);
println("dev features =0x{x}", dev.config_read(u32, 0x10));
println("guest features=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
// 0 1 2 3
// 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
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | dev features |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | guest features |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | 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
View 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);
}

View file

@ -1,3 +1,5 @@
// usingnamespace @import("index.zig");
const time = @import("time.zig");
const x86 = @import("arch/x86/index.zig");
const std = @import("std");
@ -7,7 +9,7 @@ pub const VGA_HEIGHT = 25;
pub const VGA_SIZE = VGA_WIDTH * VGA_HEIGHT;
pub var vga = VGA{
.vram = @intToPtr([*]VGAEntry, 0xb8000)[0..0x4000],
.cursor = 0,
.cursor = 80 * 2,
.foreground = Color.Black,
.background = Color.Brown,
};
@ -62,6 +64,18 @@ pub fn println(comptime format: []const u8, args: ...) void {
pub fn clear() void {
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 {
vga.writeString(string);
@ -79,7 +93,7 @@ const VGA = struct {
pub fn clear(self: *VGA) void {
std.mem.set(VGAEntry, self.vram[0..VGA_SIZE], self.entry(' '));
self.cursor = 0;
self.cursor = 80; // skip 1 line for topbar
self.updateCursor();
}