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",
|
"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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,4 +134,4 @@ volatile = "0.2.6"
|
||||||
x86_64 = "*"
|
x86_64 = "*"
|
||||||
pc-beeper = {git = "https://github.com/AbleOS/pc-beeper"}
|
pc-beeper = {git = "https://github.com/AbleOS/pc-beeper"}
|
||||||
vga = "*"
|
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) {
|
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,
|
// Backspace
|
||||||
value: character,
|
'\u{8}' => {
|
||||||
} => {
|
WRITER.lock().backspace();
|
||||||
match character {
|
KEYBUFF.lock().push(8.into());
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DecodedKey {
|
'^' => KERNEL_STATE.lock().shutdown(),
|
||||||
kind: DecodedKeyKind::RawKey,
|
chr => {
|
||||||
value: key,
|
KEYBUFF.lock().push(chr);
|
||||||
} => match KeyCode::from(key) {
|
print!("{chr}");
|
||||||
KeyCode::AltLeft => {}
|
}
|
||||||
|
},
|
||||||
KeyCode::AltRight => {}
|
DecodedKey::RawKey(key) => match KeyCode::from(key) {
|
||||||
_ => {
|
KeyCode::AltLeft | KeyCode::AltRight => (),
|
||||||
print!("{:?}", KeyCode::from(key))
|
kc => print!("{kc:?}"),
|
||||||
}
|
},
|
||||||
},
|
|
||||||
// Register a keyboard interrupt handler for the given scancode.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
PICS.lock()
|
PICS.lock()
|
||||||
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
||||||
|
|
|
@ -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),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue