Merge branch 'KFS-4' of github.com:jzck/kernel into KFS-4

This commit is contained in:
Jack Halford 2018-04-15 11:48:58 +02:00
commit 5befd11f8d
8 changed files with 115 additions and 97 deletions

View file

@ -1,6 +1,6 @@
use super::{check_signature, ACPISDTHeader}; use super::{check_signature, ACPISDTHeader};
use core::mem; use core::mem;
use cpuio; use io::{Pio,Io};
static mut DSDT: DSDT = DSDT { static mut DSDT: DSDT = DSDT {
valid: false, valid: false,
@ -86,10 +86,13 @@ pub fn init(addr: u32) -> Result<(), &'static str> {
pub fn shutdown(pm1_cnt: [u16; 2]) -> Result<(), &'static str> { pub fn shutdown(pm1_cnt: [u16; 2]) -> Result<(), &'static str> {
is_init()?; is_init()?;
let slp_typ = unsafe { DSDT.slp_typ_a } | (1 << 13); let slp_typ = unsafe { DSDT.slp_typ_a } | (1 << 13);
cpuio::outw(pm1_cnt[0], slp_typ); let mut pin: Pio<u16> = Pio::new(pm1_cnt[0]);
pin.write(slp_typ);
if pm1_cnt[1] != 0 { if pm1_cnt[1] != 0 {
let slp_typ = unsafe { DSDT.slp_typ_b } | (1 << 13); let slp_typ = unsafe { DSDT.slp_typ_b } | (1 << 13);
cpuio::outw(pm1_cnt[1], slp_typ); let mut pin: Pio<u16> = Pio::new(pm1_cnt[1]);
pin.write(slp_typ);
// cpuio::outw(pm1_cnt[1], slp_typ);
} }
Ok(()) Ok(())
} }

View file

@ -1,5 +1,5 @@
use super::{ACPISDTHeader, ACPISDTIter}; use super::{ACPISDTHeader, ACPISDTIter};
use cpuio; use io::{Io,Pio};
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -95,7 +95,10 @@ pub fn init(sdt_iter: ACPISDTIter) -> Result<(), &'static str> {
// TODO do i have to check if enabled before init ??? // TODO do i have to check if enabled before init ???
let smi_cmd = fadt_tmp.smi_commandport as u16; // TODO WHY DO I NEED THIS FUCKING CAST let smi_cmd = fadt_tmp.smi_commandport as u16; // TODO WHY DO I NEED THIS FUCKING CAST
let acpi_enable = fadt_tmp.acpi_enable; let acpi_enable = fadt_tmp.acpi_enable;
cpuio::outb(smi_cmd, acpi_enable); // send acpi enable command //TODO not sexy it !
let mut pin: Pio<u8> = Pio::new(smi_cmd);
pin.write(acpi_enable);
// cpuio::outb(smi_cmd, acpi_enable); // send acpi enable command
} }
return Ok(()); return Ok(());
} }
@ -125,10 +128,14 @@ fn get_cnt(fadt: FADT) -> [u16; 2] {
pub fn is_enable() -> Result<bool, &'static str> { pub fn is_enable() -> Result<bool, &'static str> {
let fadt = is_init()?; let fadt = is_init()?;
let pm1_cnt = get_cnt(fadt); let pm1_cnt = get_cnt(fadt);
let pin: Pio<u16> = Pio::new(pm1_cnt[0]);
if pm1_cnt[1] == 0 { if pm1_cnt[1] == 0 {
Ok(cpuio::inw(pm1_cnt[0]) & 0x1 == 0x1) Ok(pin.read() & 0x1 == 0x1)
// Ok(cpuio::inw(pm1_cnt[0]) & 0x1 == 0x1)
} else { } else {
Ok(cpuio::inw(pm1_cnt[0]) & 0x1 == 0x1 || cpuio::inw(pm1_cnt[1]) & 0x1 == 0x1) let pin2: Pio<u8> = Pio::new(pm1_cnt[1]);
Ok(pin.read() & 0x1 == 0x1 || pin2.read() & 0x1 == 0x1)
// Ok(cpuio::inw(pm1_cnt[0]) & 0x1 == 0x1 || cpuio::inw(pm1_cnt[1]) & 0x1 == 0x1)
} }
} }
@ -138,9 +145,18 @@ pub fn get_controlblock() -> Result<[u16; 2], &'static str> {
if !is_enable()? { if !is_enable()? {
Err("ACPI is not enabled") Err("ACPI is not enabled")
} else { } else {
// println!("HALT");
// flush!();
// cpuio::halt();
Ok(get_cnt(is_init()?)) // TODO redondant call to is_init Ok(get_cnt(is_init()?)) // TODO redondant call to is_init
} }
} }
pub fn reboot() -> Result<(), &'static str> {
if !is_enable()? {
Err("ACPI is not enabled")
} else {
let fadt = is_init()?;
println!("fadt on {} ({}), value is {}", fadt.resetreg.address as u32, fadt.resetreg.address as u16, fadt.resetvalue);
let mut pin: Pio<u8> = Pio::new(fadt.resetreg.address as u16);
pin.write(fadt.resetvalue);
// cpuio::outb(fadt.resetreg.address as u16, fadt.resetvalue); //TODO do it work
Ok(())
}
}

View file

@ -6,7 +6,6 @@ mod dsdt;
use core; use core;
use core::mem; use core::mem;
// use cpuio;
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -158,6 +157,17 @@ pub fn shutdown() -> Result<(), &'static str> {
dsdt::shutdown(fadt::get_controlblock()?) dsdt::shutdown(fadt::get_controlblock()?)
} }
/// Proceed to ACPI reboot
/// This function need ACPI in v2
pub fn reboot() -> Result<(), &'static str> {
is_init()?;
if unsafe {ACPI.v2} {
fadt::reboot()
} else {
Err("ACPI reboot only available in ACPI v2+")
}
}
/// Display state of ACPI /// Display state of ACPI
pub fn info() -> Result<(), &'static str> { pub fn info() -> Result<(), &'static str> {
is_init()?; is_init()?;

View file

@ -2,7 +2,8 @@ extern crate core;
// extern crate multiboot2; // extern crate multiboot2;
use acpi; use acpi;
use cpuio; use keyboard::PS2;
use io;
use core::char; use core::char;
use vga::*; use vga::*;
@ -59,16 +60,15 @@ fn help() -> Result<(), &'static str> {
/// If reboot failed, will loop on a halt cmd /// If reboot failed, will loop on a halt cmd
/// ///
fn reboot() -> ! { fn reboot() -> ! {
unsafe { asm!("cli") }; //TODO volatile ????? match acpi::reboot() {
// I will now clear the keyboard buffer Err(msg) => println!("{}", msg),
let mut buffer: u8 = 0x02; _ => println!("Unable to perform ACPI reboot."),
while buffer & 0x02 != 0 {
cpuio::inb(0x60);
buffer = cpuio::inb(0x64);
} }
cpuio::outb(0x64, 0xFE); //Send reset value to CPU //TODO doesn't work in QEMU ==> it seems that qemu cannot reboot flush!();
println!("Unable to perform reboot. Kernel will be halted"); unsafe {PS2.ps2_8042_reset()};// TODO unsafe
cpuio::halt(); println!("Unable to perform 8042 reboot. Kernel will be halted");
flush!();
io::halt();
} }
/// Shutdown the kernel /// Shutdown the kernel
@ -76,10 +76,13 @@ fn reboot() -> ! {
/// If shutdown is performed but failed, will loop on a halt cmd /// If shutdown is performed but failed, will loop on a halt cmd
/// If shutdown cannot be called, return a Err(&str) /// If shutdown cannot be called, return a Err(&str)
/// ///
fn shutdown() -> Result<(), &'static str> { fn shutdown() -> ! {
acpi::shutdown()?; match acpi::shutdown() {
println!("Unable to perform ACPI shutdown. Kernel will be halted"); Err(msg) => println!("{}", msg),
cpuio::halt(); _ => println!("Unable to perform ACPI shutdown. Kernel will be halted"),
}
flush!();
io::halt();
} }
fn hexdump(start: usize, end: usize) { fn hexdump(start: usize, end: usize) {
@ -125,6 +128,7 @@ pub fn print_stack() -> Result<(), &'static str> {
println!("ebp = {:#x}", ebp); println!("ebp = {:#x}", ebp);
println!("size = {:#X} bytes", ebp - esp); println!("size = {:#X} bytes", ebp - esp);
hexdump(esp, ebp); hexdump(esp, ebp);
flush!();
Ok(()) Ok(())
} }

View file

@ -1,56 +0,0 @@
#![allow(dead_code)]
/// Read a `u8`-sized value from `port`.
pub fn inb(port: u16) -> u8 {
// The registers for the `in` and `out` instructions are always the
// same: `a` for value, and `d` for the port address.
let result: u8;
unsafe { asm!("inb %dx, %al" : "={al}"(result) : "{dx}"(port) :: "volatile") };
result
}
/// Write a `u8`-sized `value` to `port`.
pub fn outb(port: u16, value: u8) {
unsafe { asm!("outb %al, %dx" :: "{dx}"(port), "{al}"(value) :: "volatile") };
}
/// Read a `u16`-sized value from `port`.
pub fn inw(port: u16) -> u16 {
let result: u16;
unsafe { asm!("inw %dx, %ax" : "={ax}"(result) : "{dx}"(port) :: "volatile") };
result
}
/// Write a `u8`-sized `value` to `port`.
pub fn outw(port: u16, value: u16) {
unsafe { asm!("outw %ax, %dx" :: "{dx}"(port), "{ax}"(value) :: "volatile") };
}
/// Read a `u32`-sized value from `port`.
pub fn inl(port: u16) -> u32 {
let result: u32;
unsafe { asm!("inl %dx, %eax" : "={eax}"(result) : "{dx}"(port) :: "volatile") };
result
}
/// Write a `u32`-sized `value` to `port`.
pub fn outl(port: u16, value: u32) {
unsafe { asm!("outl %eax, %dx" :: "{dx}"(port), "{eax}"(value) :: "volatile") };
}
/// Halt system
pub fn halt() -> ! {
unsafe { asm!("cli" : : : : "volatile") };
loop {
unsafe { asm!("hlt" : : : : "volatile") };
}
}
/// wait for an io operation to complete
pub fn io_wait() {
unsafe {
asm!("jmp 1f\n\t
1:jmp 2f\n\t
2:" : : : : "volatile")
}
}

View file

@ -28,3 +28,14 @@ pub trait Io {
self.write(tmp); self.write(tmp);
} }
} }
pub fn cli() {
unsafe { asm!("cli" : : : : "volatile") };
}
pub fn halt() -> ! {
cli();
loop {
unsafe { asm!("hlt" : : : : "volatile") };
}
}

View file

@ -1,7 +1,7 @@
extern crate core; extern crate core;
use cpuio;
use vga; use vga;
use io::{self,Pio,Io};
const MAX_KEYS: usize = 59; const MAX_KEYS: usize = 59;
const KEYMAP_US: [[u8; 2]; MAX_KEYS] = [ const KEYMAP_US: [[u8; 2]; MAX_KEYS] = [
@ -66,6 +66,49 @@ const KEYMAP_US: [[u8; 2]; MAX_KEYS] = [
*b"\0\0",//capslock *b"\0\0",//capslock
]; ];
pub static mut PS2: Ps2 = Ps2::new();
pub struct Ps2 {
status: Pio<u8>,
data: Pio<u8>,
}
impl Ps2 {
pub const fn new() -> Ps2 {
Ps2 {
status: Pio::new(0x64),
data: Pio::new(0x60),
}
}
pub fn clear_buffer(&self) {
let mut buffer: u8 = 0x02;
while buffer & 0x02 != 0 {
self.data.read();
buffer = self.status.read();
}
}
pub fn ps2_8042_reset(&mut self) {
io::cli();
self.clear_buffer();
self.status.write(0xFE);
}
pub fn get_scancode(&self) -> u8 {
let mut scancode = 0;
loop {
if self.data.read() != scancode {
scancode = self.data.read();
if scancode > 0 {
return scancode;
}
}
}
}
}
const TOUCH_RELEASE: u8 = 1 << 7; const TOUCH_RELEASE: u8 = 1 << 7;
fn check_key_state(key: u8) -> (bool, usize) { fn check_key_state(key: u8) -> (bool, usize) {
@ -76,23 +119,11 @@ fn check_key_state(key: u8) -> (bool, usize) {
} }
} }
fn get_scancode() -> u8 {
let mut scancode = 0;
loop {
if cpuio::inb(0x60) != scancode {
scancode = cpuio::inb(0x60);
if scancode > 0 {
return scancode;
}
}
}
}
pub fn kbd_callback() { pub fn kbd_callback() {
static mut SHIFT: bool = false; static mut SHIFT: bool = false;
static mut CTRL: bool = false; static mut CTRL: bool = false;
static mut ALT: bool = false; static mut ALT: bool = false;
let scancode = get_scancode(); let scancode = unsafe { PS2.get_scancode() };
let (is_release, scancode) = check_key_state(scancode); let (is_release, scancode) = check_key_state(scancode);
unsafe { unsafe {
//TODO remove unsafe //TODO remove unsafe

View file

@ -33,8 +33,7 @@ pub mod vga;
pub mod keyboard; pub mod keyboard;
/// simplisitc kernel commands /// simplisitc kernel commands
pub mod console; pub mod console;
/// rust wrappers around cpu I/O instructions., cpuio.rs needs to go in favour of io module /// rust wrappers around cpu I/O instructions.
pub mod cpuio;
pub mod io; pub mod io;
/// ACPI self contained module /// ACPI self contained module
pub mod acpi; pub mod acpi;