timer done
This commit is contained in:
parent
15a7f53bc2
commit
b75d97b11e
12 changed files with 69 additions and 119 deletions
|
|
@ -1,8 +0,0 @@
|
||||||
use x86::devices::pit;
|
|
||||||
use x86::devices::pic;
|
|
||||||
pub mod cpu;
|
|
||||||
|
|
||||||
pub unsafe fn init() {
|
|
||||||
pic::init();
|
|
||||||
pit::init();
|
|
||||||
}
|
|
||||||
15
kernel-rs/src/arch/x86/devices/mod.rs
Normal file
15
kernel-rs/src/arch/x86/devices/mod.rs
Normal 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();
|
||||||
|
}
|
||||||
|
|
@ -47,12 +47,6 @@ lazy_static! {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn init(memory_controller: &mut ::memory::MemoryController) {
|
|
||||||
pub fn init() {
|
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();
|
IDT.load();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use x86::structures::idt::*;
|
use x86::structures::idt::*;
|
||||||
use x86::devices::pic;
|
use x86::devices::pic;
|
||||||
|
use time;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! interrupt {
|
macro_rules! interrupt {
|
||||||
|
|
@ -45,7 +46,21 @@ pub unsafe fn acknowledge(irq: usize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupt!(0, pit, {
|
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, {
|
interrupt!(1, keyboard, {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ extern crate x86;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod paging;
|
pub mod paging;
|
||||||
pub mod interrupt;
|
pub mod interrupt;
|
||||||
pub mod device;
|
pub mod devices;
|
||||||
pub mod consts;
|
pub mod consts;
|
||||||
|
|
||||||
pub mod gdt;
|
pub mod gdt;
|
||||||
|
|
@ -52,7 +52,7 @@ pub unsafe extern "C" fn x86_rust_start(multiboot_info_addr: usize) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// set up pic, pit
|
// set up pic, pit
|
||||||
device::init();
|
devices::init();
|
||||||
|
|
||||||
// primary CPU entry point
|
// primary CPU entry point
|
||||||
::kmain();
|
::kmain();
|
||||||
|
|
|
||||||
|
|
@ -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();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
@ -26,6 +26,7 @@ fn dispatch(command: &str) -> Result<(), &'static str> {
|
||||||
"cpu" => self::cpu(),
|
"cpu" => self::cpu(),
|
||||||
"int3" => self::int3(),
|
"int3" => self::int3(),
|
||||||
"overflow" => self::overflow(),
|
"overflow" => self::overflow(),
|
||||||
|
"page_fault" => self::page_fault(),
|
||||||
|
|
||||||
_ => Err("Command unknown. (h|help for help)"),
|
_ => Err("Command unknown. (h|help for help)"),
|
||||||
}
|
}
|
||||||
|
|
@ -46,12 +47,14 @@ fn help() -> Result<(), &'static str> {
|
||||||
println!("help | h => Print this help");
|
println!("help | h => Print this help");
|
||||||
// println!("memory => Print memory areas");
|
// println!("memory => Print memory areas");
|
||||||
// println!("multiboot => Print multiboot information");
|
// println!("multiboot => Print multiboot information");
|
||||||
println!("reboot => Reboot");
|
|
||||||
// println!("sections => Print elf sections");
|
// println!("sections => Print elf sections");
|
||||||
|
println!("reboot => Reboot");
|
||||||
println!("shutdown | halt | q => Kill a kitten, then shutdown");
|
println!("shutdown | halt | q => Kill a kitten, then shutdown");
|
||||||
println!("stack => Print kernel stack in a fancy way");
|
println!("stack => Print kernel stack in a fancy way");
|
||||||
println!("regs => Print controle register");
|
println!("regs => Print controle register");
|
||||||
println!("cpu => Print cpu information");
|
println!("cpu => Print cpu information");
|
||||||
|
println!("overflow => triggers a stack overflow");
|
||||||
|
println!("page_fault => triggers a page fault on 0xdead");
|
||||||
flush!();
|
flush!();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -213,7 +216,7 @@ pub fn regs() -> Result<(), &'static str> {
|
||||||
|
|
||||||
/// Dump cpu info, should add power management info
|
/// Dump cpu info, should add power management info
|
||||||
pub fn cpu() -> Result<(), &'static str> {
|
pub fn cpu() -> Result<(), &'static str> {
|
||||||
use arch::x86::device::cpu;
|
use arch::x86::devices::cpu;
|
||||||
cpu::cpu_info().expect("cpu info not available");
|
cpu::cpu_info().expect("cpu info not available");
|
||||||
flush!();
|
flush!();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -233,3 +236,10 @@ pub fn overflow() -> Result<(), &'static str> {
|
||||||
stack_overflow();
|
stack_overflow();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn page_fault() -> Result<(), &'static str> {
|
||||||
|
unsafe {
|
||||||
|
*(0xdead as *mut u32) = 42;
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,36 +45,18 @@ pub mod arch;
|
||||||
pub use arch::x86::consts::*;
|
pub use arch::x86::consts::*;
|
||||||
/// process scheduling
|
/// process scheduling
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
/// uptime counting
|
||||||
|
pub mod time;
|
||||||
|
|
||||||
/// kernel entry point. arch module is responsible for
|
/// kernel entry point. arch module is responsible for
|
||||||
/// calling this once the core has loaded
|
/// calling this once the core has loaded
|
||||||
pub fn kmain() -> ! {
|
pub fn kmain() -> ! {
|
||||||
// heap avalaible for tracking freed frames
|
// memory init after heap is available
|
||||||
memory::init_noncore();
|
memory::init_noncore();
|
||||||
|
|
||||||
// vga is *not* cpu specific
|
// vga is *not* cpu specific I think
|
||||||
vga::init();
|
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();
|
process::schedule();
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,8 @@ pub fn fork() -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
println!("init first line");
|
fprintln!("init first line");
|
||||||
flush!();
|
|
||||||
// let i = self::fork();
|
// let i = self::fork();
|
||||||
// println!("fork={}", i);
|
// println!("fork={}", i);
|
||||||
println!("init last line");
|
fprintln!("init last line");
|
||||||
flush!();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
kernel-rs/src/time.rs
Normal file
17
kernel-rs/src/time.rs
Normal 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
|
||||||
Loading…
Reference in a new issue