Implemented task spawning
- Using `pc-keyboard` instead of custom one as it sometimes caused double-faults on keypress
This commit is contained in:
parent
f38027d128
commit
105df1bcd6
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue