diff --git a/kernel-rs/src/arch/x86/device/mod.rs b/kernel-rs/src/arch/x86/device/mod.rs new file mode 100644 index 00000000..18600155 --- /dev/null +++ b/kernel-rs/src/arch/x86/device/mod.rs @@ -0,0 +1,5 @@ +pub mod pic; + +pub fn init() { + unsafe { pic::init(); } +} diff --git a/kernel-rs/src/arch/x86/device/pic.rs b/kernel-rs/src/arch/x86/device/pic.rs new file mode 100644 index 00000000..6030f642 --- /dev/null +++ b/kernel-rs/src/arch/x86/device/pic.rs @@ -0,0 +1,64 @@ +use ::io::{Io, Pio}; + +pub static mut MASTER: Pic = Pic::new(0x20); +pub static mut SLAVE: Pic = Pic::new(0xA0); + +pub unsafe fn init() { + // Start initialization + MASTER.cmd.write(0x11); + SLAVE.cmd.write(0x11); + + // Set offsets + MASTER.data.write(0x20); + SLAVE.data.write(0x28); + + // Set up cascade + MASTER.data.write(4); + SLAVE.data.write(2); + + // Set up interrupt mode (1 is 8086/88 mode, 2 is auto EOI) + MASTER.data.write(1); + SLAVE.data.write(1); + + // Unmask interrupts + MASTER.data.write(0); + SLAVE.data.write(0); + + // Ack remaining interrupts + MASTER.ack(); + SLAVE.ack(); +} + +pub struct Pic { + cmd: Pio, + data: Pio, +} + +impl Pic { + pub const fn new(port: u16) -> Pic { + Pic { + cmd: Pio::new(port), + data: Pio::new(port + 1), + } + } + + pub fn ack(&mut self) { + self.cmd.write(0x20); + } + + pub fn mask_set(&mut self, irq: u8) { + assert!(irq < 8); + + let mut mask = self.data.read(); + mask |= 1 << irq; + self.data.write(mask); + } + + pub fn mask_clear(&mut self, irq: u8) { + assert!(irq < 8); + + let mut mask = self.data.read(); + mask &= !(1 << irq); + self.data.write(mask); + } +} diff --git a/kernel-rs/src/arch/x86/interrupt/exception.rs b/kernel-rs/src/arch/x86/interrupt/exception.rs index 40674263..489c4011 100644 --- a/kernel-rs/src/arch/x86/interrupt/exception.rs +++ b/kernel-rs/src/arch/x86/interrupt/exception.rs @@ -5,7 +5,10 @@ use x86::structures::idt::*; interrupt!(divide_by_zero, {}); interrupt!(debug, {}); interrupt!(non_maskable, {}); -interrupt!(breakpoint, {}); +interrupt!(breakpoint, { + println!("testing here dont mind me"); + flush!(); +}); interrupt!(overflow, {}); interrupt!(bound_range, {}); interrupt!(invalid_opcode, {}); diff --git a/kernel-rs/src/arch/x86/interrupt/mod.rs b/kernel-rs/src/arch/x86/interrupt/mod.rs index e024f5c2..770d0f0c 100644 --- a/kernel-rs/src/arch/x86/interrupt/mod.rs +++ b/kernel-rs/src/arch/x86/interrupt/mod.rs @@ -29,9 +29,7 @@ lazy_static! { idt.virtualization.set_handler_fn(exception::virtualization); // set up IRQs - idt.interrupts[0].set_handler_fn(irq::keyboard); - idt.interrupts[1].set_handler_fn(irq::keyboard); - idt.interrupts[2].set_handler_fn(irq::keyboard); + idt[33].set_handler_fn(irq::keyboard); idt }; } diff --git a/kernel-rs/src/arch/x86/mod.rs b/kernel-rs/src/arch/x86/mod.rs index da1e67cc..887c6d18 100644 --- a/kernel-rs/src/arch/x86/mod.rs +++ b/kernel-rs/src/arch/x86/mod.rs @@ -4,6 +4,7 @@ extern crate x86; pub mod macros; pub mod paging; pub mod interrupt; +pub mod device; use multiboot2; use acpi; @@ -25,6 +26,12 @@ pub unsafe extern fn x86_rust_start(multiboot_info_addr: usize) { // set up physical allocator ::memory::init(&boot_info); + // pic + self::device::init(); + + // set up interrupts + self::interrupt::init(); + // set up virtual mapping let mut active_table = self::paging::init(&boot_info); @@ -34,8 +41,6 @@ pub unsafe extern fn x86_rust_start(multiboot_info_addr: usize) { // after core has loaded ::memory::init_noncore(); - // set up interrupts - self::interrupt::init(); // primary CPU entry point ::kmain(); diff --git a/kernel-rs/src/io/mod.rs b/kernel-rs/src/io/mod.rs new file mode 100644 index 00000000..3bb33f5f --- /dev/null +++ b/kernel-rs/src/io/mod.rs @@ -0,0 +1,26 @@ +mod pio; + +pub use self::pio::*; + +use core::ops::{BitAnd, BitOr, Not}; + +pub trait Io { + type Value: Copy + PartialEq + BitAnd + BitOr + Not; + + fn read(&self) -> Self::Value; + fn write(&mut self, value: Self::Value); + + #[inline(always)] + fn readf(&self, flags: Self::Value) -> bool { + (self.read() & flags) as Self::Value == flags + } + + #[inline(always)] + fn writef(&mut self, flags: Self::Value, value: bool) { + let tmp: Self::Value = match value { + true => self.read() | flags, + false => self.read() & !flags, + }; + self.write(tmp); + } +} diff --git a/kernel-rs/src/io/pio.rs b/kernel-rs/src/io/pio.rs new file mode 100644 index 00000000..2582066d --- /dev/null +++ b/kernel-rs/src/io/pio.rs @@ -0,0 +1,89 @@ +use core::marker::PhantomData; + +use super::*; + +/// Generic PIO +#[derive(Copy, Clone)] +pub struct Pio { + port: u16, + value: PhantomData, +} + +impl Pio { + /// Create a PIO from a given port + pub const fn new(port: u16) -> Self { + Pio:: { + port: port, + value: PhantomData, + } + } +} + +/// Read/Write for byte PIO +impl Io for Pio { + type Value = u8; + + /// Read + #[inline(always)] + fn read(&self) -> u8 { + let value: u8; + unsafe { + asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); + } + value + } + + /// Write + #[inline(always)] + fn write(&mut self, value: u8) { + unsafe { + asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); + } + } +} + +/// Read/Write for word PIO +impl Io for Pio { + type Value = u16; + + /// Read + #[inline(always)] + fn read(&self) -> u16 { + let value: u16; + unsafe { + asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); + } + value + } + + /// Write + #[inline(always)] + fn write(&mut self, value: u16) { + unsafe { + asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); + } + } +} + +/// Read/Write for doubleword PIO +impl Io for Pio { + type Value = u32; + + /// Read + #[inline(always)] + fn read(&self) -> u32 { + let value: u32; + unsafe { + asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); + } + value + } + + /// Write + #[inline(always)] + fn write(&mut self, value: u32) { + unsafe { + asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); + } + } +} diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 5bb68a28..34129b8a 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -31,6 +31,7 @@ pub mod keyboard; pub mod console; /// rust wrappers around cpu I/O instructions. pub mod cpuio; +pub mod io; /// ACPI self contained module pub mod acpi; /// Heap allocators @@ -46,7 +47,9 @@ pub fn kmain() -> ! { // vga is specific to chipset not cpu vga::init(); + // x86::instructions::interrupts::disable(); // x86::instructions::interrupts::int3(); + // x86::instructions::interrupts::enable(); // fn stack_overflow() { stack_overflow(); } // stack_overflow(); @@ -55,8 +58,6 @@ pub fn kmain() -> ! { // *(0xdead as *mut u32) = 42; // }; - println!("at main now!"); - loop {} }