Move PS/2 driver to userspace
This commit is contained in:
parent
c957c2a105
commit
0b3be623fc
14 changed files with 178 additions and 173 deletions
3
drivers/io/Cargo.toml
Normal file
3
drivers/io/Cargo.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
[package]
|
||||
name = "io"
|
||||
version = "0.1.0"
|
67
drivers/io/src/io.rs
Normal file
67
drivers/io/src/io.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use core::cmp::PartialEq;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReadOnly<I: Io> {
|
||||
inner: I
|
||||
}
|
||||
|
||||
impl<I: Io> ReadOnly<I> {
|
||||
pub const fn new(inner: I) -> ReadOnly<I> {
|
||||
ReadOnly {
|
||||
inner: inner
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn read(&self) -> I::Value {
|
||||
self.inner.read()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn readf(&self, flags: I::Value) -> bool {
|
||||
self.inner.readf(flags)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WriteOnly<I: Io> {
|
||||
inner: I
|
||||
}
|
||||
|
||||
impl<I: Io> WriteOnly<I> {
|
||||
pub const fn new(inner: I) -> WriteOnly<I> {
|
||||
WriteOnly {
|
||||
inner: inner
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write(&mut self, value: I::Value) {
|
||||
self.inner.write(value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn writef(&mut self, flags: I::Value, value: bool) {
|
||||
self.inner.writef(flags, value)
|
||||
}
|
||||
}
|
14
drivers/io/src/lib.rs
Normal file
14
drivers/io/src/lib.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
//! I/O functions
|
||||
|
||||
#![feature(asm)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![no_std]
|
||||
|
||||
pub use self::io::*;
|
||||
pub use self::mmio::*;
|
||||
pub use self::pio::*;
|
||||
|
||||
mod io;
|
||||
mod mmio;
|
||||
mod pio;
|
31
drivers/io/src/mmio.rs
Normal file
31
drivers/io/src/mmio.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
use core::intrinsics::{volatile_load, volatile_store};
|
||||
use core::mem::uninitialized;
|
||||
use core::ops::{BitAnd, BitOr, Not};
|
||||
|
||||
use super::io::Io;
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct Mmio<T> {
|
||||
value: T,
|
||||
}
|
||||
|
||||
impl<T> Mmio<T> {
|
||||
/// Create a new Mmio without initializing
|
||||
pub fn new() -> Self {
|
||||
Mmio {
|
||||
value: unsafe { uninitialized() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Io for Mmio<T> where T: Copy + PartialEq + BitAnd<Output = T> + BitOr<Output = T> + Not<Output = T> {
|
||||
type Value = T;
|
||||
|
||||
fn read(&self) -> T {
|
||||
unsafe { volatile_load(&self.value) }
|
||||
}
|
||||
|
||||
fn write(&mut self, value: T) {
|
||||
unsafe { volatile_store(&mut self.value, value) };
|
||||
}
|
||||
}
|
89
drivers/io/src/pio.rs
Normal file
89
drivers/io/src/pio.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use core::marker::PhantomData;
|
||||
|
||||
use super::io::Io;
|
||||
|
||||
/// 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");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue