1
0
Fork 0
forked from AbleOS/ableos

Implemented task spawning

- Using `pc-keyboard` instead of custom one as it sometimes caused double-faults on keypress
This commit is contained in:
Erin 2022-06-14 17:27:30 +02:00 committed by ondra05
parent f38027d128
commit 105df1bcd6
6 changed files with 70 additions and 58 deletions

7
Cargo.lock generated
View file

@ -44,6 +44,7 @@ dependencies = [
"log", "log",
"logos", "logos",
"pc-beeper", "pc-beeper",
"pc-keyboard",
"pic8259", "pic8259",
"picorand", "picorand",
"pretty-hex", "pretty-hex",
@ -608,6 +609,12 @@ dependencies = [
"x86_64", "x86_64",
] ]
[[package]]
name = "pc-keyboard"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6f2d937e3b8d63449b01401e2bae4041bc9dd1129c2e3e0d239407cf6635ac"
[[package]] [[package]]
name = "pic8259" name = "pic8259"
version = "0.10.2" version = "0.10.2"

View file

@ -54,6 +54,7 @@ libwasm = {git="https://git.ablecorp.us:443/able/libwasm.git"}
axel = { git = "https://git.ablecorp.us/able/aos_userland" } axel = { git = "https://git.ablecorp.us/able/aos_userland" }
versioning = { git = "https://git.ablecorp.us/able/aos_userland" } versioning = { git = "https://git.ablecorp.us/able/aos_userland" }
embedded-graphics="*" embedded-graphics="*"
pc-keyboard = "0.5"

View file

@ -94,66 +94,40 @@ extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFr
} }
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) { extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
use crate::keyboard::{ use pc_keyboard::{
CustomLayout, CustomScancodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode, layouts::Us104Key, DecodedKey, HandleControl, KeyCode, Keyboard, ScancodeSet1,
Keyboard,
}; };
use spin::Mutex; use spin::Mutex;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
static KEYBOARD: Lazy<Mutex<Keyboard<CustomLayout, CustomScancodeSet>>> = Lazy::new(|| { static KEYBOARD: Lazy<Mutex<Keyboard<Us104Key, ScancodeSet1>>> =
Mutex::new(Keyboard::new( Lazy::new(|| Mutex::new(Keyboard::new(Us104Key, ScancodeSet1, HandleControl::Ignore)));
CustomLayout::new_us104key(),
CustomScancodeSet::default(),
HandleControl::Ignore,
))
});
let mut keyboard = KEYBOARD.lock(); let mut keyboard = KEYBOARD.lock();
let mut port = Port::new(0x60); if let Ok(Some(key)) = keyboard
let scancode: u8 = unsafe { port.read() }; .add_byte(unsafe { Port::new(0x60).read() })
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) { .map(|x| x.and_then(|ev| keyboard.process_keyevent(ev)))
if let Some(key) = keyboard.process_keyevent(key_event) { {
match key { match key {
DecodedKey { DecodedKey::Unicode(chr) => match chr {
kind: DecodedKeyKind::Unicode,
value: character,
} => {
match character {
// Backspace // Backspace
8 => { '\u{8}' => {
WRITER.lock().backspace(); WRITER.lock().backspace();
KEYBUFF.lock().push(8_u8 as _); KEYBUFF.lock().push(8.into());
// print!(" ");
// WRITER.lock().backspace();
} }
'^' => KERNEL_STATE.lock().shutdown(),
0x5E => KERNEL_STATE.lock().shutdown(), chr => {
KEYBUFF.lock().push(chr);
_ => { print!("{chr}");
let mut buff = KEYBUFF.lock();
buff.push(character as u8 as char);
print!("{}", char::try_from(character).unwrap());
}
}
}
DecodedKey {
kind: DecodedKeyKind::RawKey,
value: key,
} => match KeyCode::from(key) {
KeyCode::AltLeft => {}
KeyCode::AltRight => {}
_ => {
print!("{:?}", KeyCode::from(key))
} }
}, },
// Register a keyboard interrupt handler for the given scancode. DecodedKey::RawKey(key) => match KeyCode::from(key) {
} KeyCode::AltLeft | KeyCode::AltRight => (),
kc => print!("{kc:?}"),
},
} }
} }
unsafe { unsafe {
PICS.lock() PICS.lock()
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8()); .notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());

View file

@ -78,6 +78,22 @@ pub unsafe extern "C" fn switch_to_next() -> ! {
in(reg) sp, in(reg) sp,
options(noreturn), options(noreturn),
), ),
Task::Spawn(_) => todo!("task spawning"), Task::Spawn {
function,
stack_start,
} => asm!(
"add rsp, 160", // Move above saved registries
"mov [rsp], {ip}", // Set task's instruction pointer
"mov [rsp + 24], {sp}", // Set task's stack pointer
// Signalise the end of the interrupt and return
"mov al, 32",
"out 20h, al",
"iretq",
ip = in(reg) function,
sp = in(reg) stack_start,
options(noreturn),
),
} }
} }

View file

@ -1,6 +1,7 @@
#![allow(clippy::empty_loop)] #![allow(clippy::empty_loop)]
use crate::arch::drivers::sysinfo::master; use crate::arch::drivers::sysinfo::master;
use crate::scheduler::SCHEDULER;
use crate::{ use crate::{
arch::{init, sloop}, arch::{init, sloop},
relib::network::socket::{SimpleSock, Socket}, relib::network::socket::{SimpleSock, Socket},
@ -24,8 +25,9 @@ pub fn kernel_main() -> ! {
log::set_max_level(log::LevelFilter::Off); log::set_max_level(log::LevelFilter::Off);
} }
// start_facepalm(); x86_64::instructions::interrupts::without_interrupts(|| {
scratchpad(); SCHEDULER.lock().enqueue_spawn(scratchpad);
});
sloop() sloop()
} }

View file

@ -3,9 +3,12 @@ use spin::{Lazy, Mutex};
pub static SCHEDULER: Lazy<Mutex<Scheduler>> = Lazy::new(|| Mutex::new(Scheduler::default())); pub static SCHEDULER: Lazy<Mutex<Scheduler>> = Lazy::new(|| Mutex::new(Scheduler::default()));
/// Task's stack size (in kiB)
const STACK_SIZE: usize = 512;
pub enum Task { pub enum Task {
Suspended(u64), Suspended(u64),
Spawn(fn()), Spawn { function: fn(), stack_start: usize },
} }
#[derive(Default)] #[derive(Default)]
@ -14,8 +17,17 @@ pub struct Scheduler {
} }
impl Scheduler { impl Scheduler {
pub fn enqueue_spawn(&mut self, f: fn()) { pub fn enqueue_spawn(&mut self, function: fn()) {
self.task_queue.push_back(Task::Spawn(f)); self.task_queue.push_back(Task::Spawn {
function,
stack_start: unsafe {
let size = STACK_SIZE * 1024;
alloc::alloc::alloc(
alloc::alloc::Layout::from_size_align(size, 1).expect("invalid layout"),
)
.add(size - 1) as _
},
});
} }
pub fn enqueue_suspended(&mut self, sp: u64) { pub fn enqueue_suspended(&mut self, sp: u64) {