pio and x86/pic

This commit is contained in:
Jack Halford 2018-03-29 20:29:04 +02:00
parent 6d8c31b42c
commit c24ac47698
8 changed files with 199 additions and 8 deletions

View file

@ -0,0 +1,5 @@
pub mod pic;
pub fn init() {
unsafe { pic::init(); }
}

View file

@ -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<u8>,
data: Pio<u8>,
}
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);
}
}

View file

@ -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, {});

View file

@ -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
};
}

View file

@ -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();

26
kernel-rs/src/io/mod.rs Normal file
View file

@ -0,0 +1,26 @@
mod pio;
pub use self::pio::*;
use core::ops::{BitAnd, BitOr, Not};
pub trait Io {
type Value: Copy + PartialEq + BitAnd<Output = Self::Value> + BitOr<Output = Self::Value> + Not<Output = Self::Value>;
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);
}
}

89
kernel-rs/src/io/pio.rs Normal file
View file

@ -0,0 +1,89 @@
use core::marker::PhantomData;
use super::*;
/// Generic PIO
#[derive(Copy, Clone)]
pub struct Pio<T> {
port: u16,
value: PhantomData<T>,
}
impl<T> Pio<T> {
/// Create a PIO from a given port
pub const fn new(port: u16) -> Self {
Pio::<T> {
port: port,
value: PhantomData,
}
}
}
/// Read/Write for byte PIO
impl Io for Pio<u8> {
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<u16> {
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<u32> {
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");
}
}
}

View file

@ -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 {}
}