pio and x86/pic
This commit is contained in:
parent
6d8c31b42c
commit
c24ac47698
8 changed files with 199 additions and 8 deletions
5
kernel-rs/src/arch/x86/device/mod.rs
Normal file
5
kernel-rs/src/arch/x86/device/mod.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
pub mod pic;
|
||||
|
||||
pub fn init() {
|
||||
unsafe { pic::init(); }
|
||||
}
|
||||
64
kernel-rs/src/arch/x86/device/pic.rs
Normal file
64
kernel-rs/src/arch/x86/device/pic.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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, {});
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
26
kernel-rs/src/io/mod.rs
Normal 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
89
kernel-rs/src/io/pio.rs
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue