timer done

This commit is contained in:
Jack Halford 2018-06-06 16:59:16 +02:00
parent 15a7f53bc2
commit b75d97b11e
12 changed files with 69 additions and 119 deletions

View file

@ -1,8 +0,0 @@
use x86::devices::pit;
use x86::devices::pic;
pub mod cpu;
pub unsafe fn init() {
pic::init();
pit::init();
}

View file

@ -0,0 +1,15 @@
use x86::devices::pit;
use x86::devices::pic;
pub mod cpu;
use x86::instructions::interrupts;
static CHAN0_DIVISOR: u16 = 2685;
pub unsafe fn init() {
pic::init_cascade();
pic::disable_irqs();
pic::enable_irq(0);
pic::enable_irq(1);
pit::CHAN0.set_divisor(CHAN0_DIVISOR);
interrupts::enable();
}

View file

@ -47,12 +47,6 @@ lazy_static! {
};
}
// pub fn init(memory_controller: &mut ::memory::MemoryController) {
pub fn init() {
// let double_fault_stack = memory_controller.alloc_stack(1)
// .expect("could not allocate double fault stack");
// println!("DF stack: {:#?}", double_fault_stack);
// flush!();
IDT.load();
}

View file

@ -1,5 +1,6 @@
use x86::structures::idt::*;
use x86::devices::pic;
use time;
#[macro_export]
macro_rules! interrupt {
@ -45,7 +46,21 @@ pub unsafe fn acknowledge(irq: usize) {
}
interrupt!(0, pit, {
fprintln!("got pit (irq0)");
/// t = 1/f
/// pit freq = 1.193182 MHz
/// chan0 divisor = 2685
/// PIT_RATE in us
const PIT_RATE: u32 = 2_251;
{
let mut offset = time::OFFSET.lock();
let sum = offset.1 + PIT_RATE;
offset.1 = sum % 1_000_000;
offset.0 += sum / 1_000_000;
if sum > 1_000_000 {
fprintln!("uptime: {}s", offset.0);
}
}
unsafe { pic::MASTER.ack() };
});
interrupt!(1, keyboard, {

View file

@ -3,7 +3,7 @@ extern crate x86;
#[macro_use]
pub mod paging;
pub mod interrupt;
pub mod device;
pub mod devices;
pub mod consts;
pub mod gdt;
@ -52,7 +52,7 @@ pub unsafe extern "C" fn x86_rust_start(multiboot_info_addr: usize) {
// }
// set up pic, pit
device::init();
devices::init();
// primary CPU entry point
::kmain();

View file

@ -1,73 +0,0 @@
use core::ptr;
use super::paging::ActivePageTable;
// use super::paging::entry::EntryFlags;
#[thread_local]
pub static mut PTI_CPU_STACK: [u8; 256] = [0; 256];
#[thread_local]
pub static mut PTI_CONTEXT_STACK: usize = 0;
#[inline(always)]
unsafe fn switch_stack(old: usize, new: usize) {
let old_esp: usize;
// save the old esp
asm!("" : "={esp}"(old_esp) : : : "intel", "volatile");
let offset_esp = old - old_esp;
let new_esp = new - offset_esp;
ptr::copy_nonoverlapping(old_esp as *const u8, new_esp as *mut u8, offset_esp);
// switch the esp with the new one
asm!("" : : "{esp}"(new_esp) : : "intel", "volatile");
}
#[inline(always)]
pub unsafe fn map() {
// {
// let mut active_table = unsafe { ActivePageTable::new() };
//
// // Map kernel heap
// let address = active_table.p4()[::KERNEL_HEAP_PML4].address();
// let frame = Frame::containing_address(address);
// let mut flags = active_table.p4()[::KERNEL_HEAP_PML4].flags();
// flags.remove(EntryFlags::PRESENT);
// active_table.p4_mut()[::KERNEL_HEAP_PML4].set(frame, flags);
//
// // Reload page tables
// active_table.flush_all();
// }
// Switch to per-context stack
switch_stack(
PTI_CPU_STACK.as_ptr() as usize + PTI_CPU_STACK.len(),
PTI_CONTEXT_STACK,
);
}
#[inline(always)]
pub unsafe fn unmap() {
// Switch to per-CPU stack
switch_stack(
PTI_CONTEXT_STACK,
PTI_CPU_STACK.as_ptr() as usize + PTI_CPU_STACK.len(),
);
// {
// let mut active_table = unsafe { ActivePageTable::new() };
//
// // Unmap kernel heap
// let address = active_table.p4()[::KERNEL_HEAP_PML4].address();
// let frame = Frame::containing_address(address);
// let mut flags = active_table.p4()[::KERNEL_HEAP_PML4].flags();
// flags.insert(EntryFlags::PRESENT);
// active_table.p4_mut()[::KERNEL_HEAP_PML4].set(frame, flags);
//
// // Reload page tables
// active_table.flush_all();
// }
}

View file

@ -26,6 +26,7 @@ fn dispatch(command: &str) -> Result<(), &'static str> {
"cpu" => self::cpu(),
"int3" => self::int3(),
"overflow" => self::overflow(),
"page_fault" => self::page_fault(),
_ => Err("Command unknown. (h|help for help)"),
}
@ -46,12 +47,14 @@ fn help() -> Result<(), &'static str> {
println!("help | h => Print this help");
// println!("memory => Print memory areas");
// println!("multiboot => Print multiboot information");
println!("reboot => Reboot");
// println!("sections => Print elf sections");
println!("reboot => Reboot");
println!("shutdown | halt | q => Kill a kitten, then shutdown");
println!("stack => Print kernel stack in a fancy way");
println!("regs => Print controle register");
println!("cpu => Print cpu information");
println!("overflow => triggers a stack overflow");
println!("page_fault => triggers a page fault on 0xdead");
flush!();
Ok(())
}
@ -213,7 +216,7 @@ pub fn regs() -> Result<(), &'static str> {
/// Dump cpu info, should add power management info
pub fn cpu() -> Result<(), &'static str> {
use arch::x86::device::cpu;
use arch::x86::devices::cpu;
cpu::cpu_info().expect("cpu info not available");
flush!();
Ok(())
@ -233,3 +236,10 @@ pub fn overflow() -> Result<(), &'static str> {
stack_overflow();
Ok(())
}
pub fn page_fault() -> Result<(), &'static str> {
unsafe {
*(0xdead as *mut u32) = 42;
};
Ok(())
}

View file

@ -45,36 +45,18 @@ pub mod arch;
pub use arch::x86::consts::*;
/// process scheduling
pub mod process;
/// uptime counting
pub mod time;
/// kernel entry point. arch module is responsible for
/// calling this once the core has loaded
pub fn kmain() -> ! {
// heap avalaible for tracking freed frames
// memory init after heap is available
memory::init_noncore();
// vga is *not* cpu specific
// vga is *not* cpu specific I think
vga::init();
// unsafe {
// *(0xdead as *mut u32) = 42;
// };
// x86::instructions::interrupts::int3();
// println!("flags: {:?}", x86::registers::flags::flags());
// flush!();
// let sp = (::USER_STACK_OFFSET + ::USER_STACK_SIZE).as_u32();
// let sp: u32;
// unsafe {
// asm!("mov %ebp, $0" : "=r" (sp));
// }
// unsafe {
// arch::x86::usermode(ip, sp, 0);
// }
// unreachable!()
process::schedule();
unreachable!();
}

View file

@ -66,10 +66,8 @@ pub fn fork() -> i32 {
}
pub fn init() {
println!("init first line");
flush!();
fprintln!("init first line");
// let i = self::fork();
// println!("fork={}", i);
println!("init last line");
flush!();
fprintln!("init last line");
}

17
kernel-rs/src/time.rs Normal file
View file

@ -0,0 +1,17 @@
use spin::Mutex;
/// Kernel start time, measured in (seconds, microseconds) since Unix epoch
pub static START: Mutex<(u32, u32)> = Mutex::new((0, 0));
/// Kernel up time, measured in (seconds, microseconds) since `START_TIME`
pub static OFFSET: Mutex<(u32, u32)> = Mutex::new((0, 0));
pub fn monotonic() -> (u32, u32) {
*OFFSET.lock()
}
pub fn realtime() -> (u32, u32) {
let offset = monotonic();
let start = *START.lock();
let sum = start.1 + offset.1;
(start.0 + offset.0 + sum / 1_000_000, sum % 1_000_000)
}

@ -1 +1 @@
Subproject commit 0da7a6b2bfafec479a990bb0dac8f4bd58b9fd79
Subproject commit 229c4acbbe81bf4837bd05714b99614ada9dd2b3