Fill in all exception and IRQ entries. Handle PIT, keyboard IRQs

This commit is contained in:
Jeremy Soller 2016-08-31 17:45:21 -06:00
parent a9a8c2b340
commit f784e9a06a
16 changed files with 441 additions and 219 deletions

View file

@ -0,0 +1,90 @@
use core::slice;
use spin::Mutex;
use memory::Frame;
use paging::{ActivePageTable, PhysicalAddress, entry};
/// The info of the VBE mode
#[derive(Copy, Clone, Default, Debug)]
#[repr(packed)]
pub struct VBEModeInfo {
attributes: u16,
win_a: u8,
win_b: u8,
granularity: u16,
winsize: u16,
segment_a: u16,
segment_b: u16,
winfuncptr: u32,
bytesperscanline: u16,
pub xresolution: u16,
pub yresolution: u16,
xcharsize: u8,
ycharsize: u8,
numberofplanes: u8,
bitsperpixel: u8,
numberofbanks: u8,
memorymodel: u8,
banksize: u8,
numberofimagepages: u8,
unused: u8,
redmasksize: u8,
redfieldposition: u8,
greenmasksize: u8,
greenfieldposition: u8,
bluemasksize: u8,
bluefieldposition: u8,
rsvdmasksize: u8,
rsvdfieldposition: u8,
directcolormodeinfo: u8,
physbaseptr: u32,
offscreenmemoryoffset: u32,
offscreenmemsize: u16,
}
pub static DISPLAY: Mutex<Option<Display>> = Mutex::new(None);
pub unsafe fn init(active_table: &mut ActivePageTable) {
active_table.identity_map(Frame::containing_address(PhysicalAddress::new(0x5200)), entry::PRESENT | entry::NO_EXECUTE);
let mode_info = &*(0x5200 as *const VBEModeInfo);
if mode_info.physbaseptr > 0 {
let width = mode_info.xresolution as usize;
let height = mode_info.yresolution as usize;
let start = mode_info.physbaseptr as usize;
let size = width * height;
{
let start_frame = Frame::containing_address(PhysicalAddress::new(start));
let end_frame = Frame::containing_address(PhysicalAddress::new(start + size * 4 - 1));
for frame in Frame::range_inclusive(start_frame, end_frame) {
active_table.identity_map(frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
}
}
for i in 0..size {
let c = ((i * 256)/size) as u32 & 0xFF;
*(start as *mut u32).offset(i as isize) = (c << 16) | (c << 8) | c;
}
//memset(start as *mut u8, 0, size * 4);
*DISPLAY.lock() = Some(Display::new(width, height, slice::from_raw_parts_mut(start as *mut u32, size)));
}
}
/// A display
pub struct Display {
pub width: usize,
pub height: usize,
pub data: &'static mut [u32],
}
impl Display {
fn new(width: usize, height: usize, data: &'static mut [u32]) -> Self {
Display {
width: width,
height: height,
data: data,
}
}
}

View file

@ -0,0 +1,9 @@
use paging::ActivePageTable;
pub mod display;
pub mod ps2;
pub unsafe fn init(active_table: &mut ActivePageTable){
display::init(active_table);
ps2::init();
}

View file

@ -0,0 +1,73 @@
use spin::Mutex;
use io::{Io, Pio, ReadOnly, WriteOnly};
pub static PS2: Mutex<Ps2> = Mutex::new(Ps2::new());
pub unsafe fn init() {
PS2.lock().init();
}
mod status {
bitflags! {
pub flags Flags: u8 {
const OUTPUT_FULL = 1,
const INPUT_FULL = 1 << 1,
const SYSTEM = 1 << 2,
const COMMAND = 1 << 3,
const TIME_OUT = 1 << 6,
const PARITY = 1 << 7
}
}
}
mod config {
bitflags! {
pub flags Flags: u8 {
const FIRST_INTERRUPT = 1,
const SECOND_INTERRUPT = 1 << 1,
const SYSTEM = 1 << 2,
const FIRST_DISABLE = 1 << 4,
const SECOND_DISABLE = 1 << 5,
const FIRST_TRANSLATE = 1 << 6
}
}
}
#[repr(u8)]
enum Command {
ReadConfig = 0x20,
WriteConfig = 0x60,
DisableSecond = 0xA7,
EnableSecond = 0xA8,
TestSecond = 0xA9,
TestController = 0xAA,
TestFirst = 0xAB,
Diagnostic = 0xAC,
DisableFirst = 0xAD,
EnableFirst = 0xAE,
WriteSecond = 0xD4
}
pub struct Ps2 {
pub data: Pio<u8>,
pub status: ReadOnly<Pio<u8>>,
pub command: WriteOnly<Pio<u8>>
}
impl Ps2 {
pub const fn new() -> Ps2 {
Ps2 {
data: Pio::new(0x60),
status: ReadOnly::new(Pio::new(0x64)),
command: WriteOnly::new(Pio::new(0x64))
}
}
pub fn init(&mut self) {
print!("Status {:?}\n", status::Flags::from_bits_truncate(self.status.read()));
self.command.write(Command::ReadConfig as u8);
print!("Config {:?}\n", config::Flags::from_bits_truncate(self.data.read()));
}
}