Merge branch 'KFS-4' of github.com:jzck/kernel into KFS-4
This commit is contained in:
commit
5befd11f8d
8 changed files with 115 additions and 97 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use super::{check_signature, ACPISDTHeader};
|
||||
use core::mem;
|
||||
use cpuio;
|
||||
use io::{Pio,Io};
|
||||
|
||||
static mut DSDT: DSDT = DSDT {
|
||||
valid: false,
|
||||
|
|
@ -86,10 +86,13 @@ pub fn init(addr: u32) -> Result<(), &'static str> {
|
|||
pub fn shutdown(pm1_cnt: [u16; 2]) -> Result<(), &'static str> {
|
||||
is_init()?;
|
||||
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 {
|
||||
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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use super::{ACPISDTHeader, ACPISDTIter};
|
||||
use cpuio;
|
||||
use io::{Io,Pio};
|
||||
|
||||
#[repr(C)]
|
||||
#[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 ???
|
||||
let smi_cmd = fadt_tmp.smi_commandport as u16; // TODO WHY DO I NEED THIS FUCKING CAST
|
||||
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(());
|
||||
}
|
||||
|
|
@ -125,10 +128,14 @@ fn get_cnt(fadt: FADT) -> [u16; 2] {
|
|||
pub fn is_enable() -> Result<bool, &'static str> {
|
||||
let fadt = is_init()?;
|
||||
let pm1_cnt = get_cnt(fadt);
|
||||
let pin: Pio<u16> = Pio::new(pm1_cnt[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 {
|
||||
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()? {
|
||||
Err("ACPI is not enabled")
|
||||
} else {
|
||||
// println!("HALT");
|
||||
// flush!();
|
||||
// cpuio::halt();
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ mod dsdt;
|
|||
|
||||
use core;
|
||||
use core::mem;
|
||||
// use cpuio;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
@ -158,6 +157,17 @@ pub fn shutdown() -> Result<(), &'static str> {
|
|||
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
|
||||
pub fn info() -> Result<(), &'static str> {
|
||||
is_init()?;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ extern crate core;
|
|||
// extern crate multiboot2;
|
||||
|
||||
use acpi;
|
||||
use cpuio;
|
||||
use keyboard::PS2;
|
||||
use io;
|
||||
use core::char;
|
||||
use vga::*;
|
||||
|
||||
|
|
@ -59,16 +60,15 @@ fn help() -> Result<(), &'static str> {
|
|||
/// If reboot failed, will loop on a halt cmd
|
||||
///
|
||||
fn reboot() -> ! {
|
||||
unsafe { asm!("cli") }; //TODO volatile ?????
|
||||
// I will now clear the keyboard buffer
|
||||
let mut buffer: u8 = 0x02;
|
||||
while buffer & 0x02 != 0 {
|
||||
cpuio::inb(0x60);
|
||||
buffer = cpuio::inb(0x64);
|
||||
match acpi::reboot() {
|
||||
Err(msg) => println!("{}", msg),
|
||||
_ => println!("Unable to perform ACPI reboot."),
|
||||
}
|
||||
cpuio::outb(0x64, 0xFE); //Send reset value to CPU //TODO doesn't work in QEMU ==> it seems that qemu cannot reboot
|
||||
println!("Unable to perform reboot. Kernel will be halted");
|
||||
cpuio::halt();
|
||||
flush!();
|
||||
unsafe {PS2.ps2_8042_reset()};// TODO unsafe
|
||||
println!("Unable to perform 8042 reboot. Kernel will be halted");
|
||||
flush!();
|
||||
io::halt();
|
||||
}
|
||||
|
||||
/// Shutdown the kernel
|
||||
|
|
@ -76,10 +76,13 @@ fn reboot() -> ! {
|
|||
/// If shutdown is performed but failed, will loop on a halt cmd
|
||||
/// If shutdown cannot be called, return a Err(&str)
|
||||
///
|
||||
fn shutdown() -> Result<(), &'static str> {
|
||||
acpi::shutdown()?;
|
||||
println!("Unable to perform ACPI shutdown. Kernel will be halted");
|
||||
cpuio::halt();
|
||||
fn shutdown() -> ! {
|
||||
match acpi::shutdown() {
|
||||
Err(msg) => println!("{}", msg),
|
||||
_ => println!("Unable to perform ACPI shutdown. Kernel will be halted"),
|
||||
}
|
||||
flush!();
|
||||
io::halt();
|
||||
}
|
||||
|
||||
fn hexdump(start: usize, end: usize) {
|
||||
|
|
@ -125,6 +128,7 @@ pub fn print_stack() -> Result<(), &'static str> {
|
|||
println!("ebp = {:#x}", ebp);
|
||||
println!("size = {:#X} bytes", ebp - esp);
|
||||
hexdump(esp, ebp);
|
||||
flush!();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
@ -28,3 +28,14 @@ pub trait Io {
|
|||
self.write(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cli() {
|
||||
unsafe { asm!("cli" : : : : "volatile") };
|
||||
}
|
||||
|
||||
pub fn halt() -> ! {
|
||||
cli();
|
||||
loop {
|
||||
unsafe { asm!("hlt" : : : : "volatile") };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
extern crate core;
|
||||
|
||||
use cpuio;
|
||||
use vga;
|
||||
use io::{self,Pio,Io};
|
||||
|
||||
const MAX_KEYS: usize = 59;
|
||||
const KEYMAP_US: [[u8; 2]; MAX_KEYS] = [
|
||||
|
|
@ -66,6 +66,49 @@ const KEYMAP_US: [[u8; 2]; MAX_KEYS] = [
|
|||
*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;
|
||||
|
||||
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() {
|
||||
static mut SHIFT: bool = false;
|
||||
static mut CTRL: 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);
|
||||
unsafe {
|
||||
//TODO remove unsafe
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ pub mod vga;
|
|||
pub mod keyboard;
|
||||
/// simplisitc kernel commands
|
||||
pub mod console;
|
||||
/// rust wrappers around cpu I/O instructions., cpuio.rs needs to go in favour of io module
|
||||
pub mod cpuio;
|
||||
/// rust wrappers around cpu I/O instructions.
|
||||
pub mod io;
|
||||
/// ACPI self contained module
|
||||
pub mod acpi;
|
||||
|
|
|
|||
Loading…
Reference in a new issue