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.
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
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
|
||||
export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
||||
assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);
|
||||
|
|
|
|||
|
|
@ -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
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 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();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue