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",
"logos",
"pc-beeper",
"pc-keyboard",
"pic8259",
"picorand",
"pretty-hex",
@ -608,6 +609,12 @@ dependencies = [
"x86_64",
]
[[package]]
name = "pc-keyboard"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6f2d937e3b8d63449b01401e2bae4041bc9dd1129c2e3e0d239407cf6635ac"
[[package]]
name = "pic8259"
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" }
versioning = { git = "https://git.ablecorp.us/able/aos_userland" }
embedded-graphics="*"
pc-keyboard = "0.5"
@ -133,4 +134,4 @@ volatile = "0.2.6"
x86_64 = "*"
pc-beeper = {git = "https://github.com/AbleOS/pc-beeper"}
vga = "*"
acpi = "4.1.0"
acpi = "4.1.0"

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) {
use crate::keyboard::{
CustomLayout, CustomScancodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode,
Keyboard,
use pc_keyboard::{
layouts::Us104Key, DecodedKey, HandleControl, KeyCode, Keyboard, ScancodeSet1,
};
use spin::Mutex;
use x86_64::instructions::port::Port;
static KEYBOARD: Lazy<Mutex<Keyboard<CustomLayout, CustomScancodeSet>>> = Lazy::new(|| {
Mutex::new(Keyboard::new(
CustomLayout::new_us104key(),
CustomScancodeSet::default(),
HandleControl::Ignore,
))
});
static KEYBOARD: Lazy<Mutex<Keyboard<Us104Key, ScancodeSet1>>> =
Lazy::new(|| Mutex::new(Keyboard::new(Us104Key, ScancodeSet1, HandleControl::Ignore)));
let mut keyboard = KEYBOARD.lock();
let mut port = Port::new(0x60);
let scancode: u8 = unsafe { port.read() };
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
if let Some(key) = keyboard.process_keyevent(key_event) {
match key {
DecodedKey {
kind: DecodedKeyKind::Unicode,
value: character,
} => {
match character {
// Backspace
8 => {
WRITER.lock().backspace();
KEYBUFF.lock().push(8_u8 as _);
// print!(" ");
// WRITER.lock().backspace();
}
0x5E => KERNEL_STATE.lock().shutdown(),
_ => {
let mut buff = KEYBUFF.lock();
buff.push(character as u8 as char);
print!("{}", char::try_from(character).unwrap());
}
}
if let Ok(Some(key)) = keyboard
.add_byte(unsafe { Port::new(0x60).read() })
.map(|x| x.and_then(|ev| keyboard.process_keyevent(ev)))
{
match key {
DecodedKey::Unicode(chr) => match chr {
// Backspace
'\u{8}' => {
WRITER.lock().backspace();
KEYBUFF.lock().push(8.into());
}
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.
}
'^' => KERNEL_STATE.lock().shutdown(),
chr => {
KEYBUFF.lock().push(chr);
print!("{chr}");
}
},
DecodedKey::RawKey(key) => match KeyCode::from(key) {
KeyCode::AltLeft | KeyCode::AltRight => (),
kc => print!("{kc:?}"),
},
}
}
unsafe {
PICS.lock()
.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,
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)]
use crate::arch::drivers::sysinfo::master;
use crate::scheduler::SCHEDULER;
use crate::{
arch::{init, sloop},
relib::network::socket::{SimpleSock, Socket},
@ -24,8 +25,9 @@ pub fn kernel_main() -> ! {
log::set_max_level(log::LevelFilter::Off);
}
// start_facepalm();
scratchpad();
x86_64::instructions::interrupts::without_interrupts(|| {
SCHEDULER.lock().enqueue_spawn(scratchpad);
});
sloop()
}

View file

@ -3,9 +3,12 @@ use spin::{Lazy, Mutex};
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 {
Suspended(u64),
Spawn(fn()),
Spawn { function: fn(), stack_start: usize },
}
#[derive(Default)]
@ -14,8 +17,17 @@ pub struct Scheduler {
}
impl Scheduler {
pub fn enqueue_spawn(&mut self, f: fn()) {
self.task_queue.push_back(Task::Spawn(f));
pub fn enqueue_spawn(&mut self, function: fn()) {
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) {