Interrupt Forwarding (#22)

Co-authored-by: Talha Qamar <qamartalha@proton.me>
Reviewed-on: https://git.ablecorp.us/AbleOS/ableos/pulls/22
Co-authored-by: kodin <kodin@yourmoms.house>
Co-committed-by: kodin <kodin@yourmoms.house>
This commit is contained in:
kodin 2024-11-26 15:53:50 -06:00 committed by koniifer
parent 685c6f0b20
commit 5d152811b2
7 changed files with 77 additions and 16 deletions

View file

@ -62,7 +62,7 @@ extern "x86-interrupt" fn page_fault(
}
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
// interrupt(Interrupt::Timer);
interrupt(Interrupt::Timer);
unsafe {
LAPIC.end_of_interrupt();
@ -85,6 +85,7 @@ extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
fn interrupt(interrupt_type: Interrupt) {
use crate::arch::INTERRUPT_LIST;
use crate::kmain::EXECUTOR;
let il = INTERRUPT_LIST.lock();
let val = il.list.get(&interrupt_type).unwrap();
@ -107,4 +108,8 @@ fn interrupt(interrupt_type: Interrupt) {
// log::info!("{}", buffer);
}
unsafe{
EXECUTOR.send_interrupt(interrupt_type as u8);
}
}

View file

@ -1,5 +1,7 @@
//! Environment call handling routines
use log::log;
use {alloc::boxed::Box, core::cell::LazyCell, hbvm::mem::Address};
use crate::{
@ -242,6 +244,15 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
vm.registers[3] = x
}
}
6 => { // Wait till interrupt
use crate::kmain::EXECUTOR;
let interrupt_type = vm.registers[3].cast::<u8>();
info!("Interrupt subscribled: {}", interrupt_type);
unsafe{
EXECUTOR.pause(pid.clone());
LazyCell::<Executor>::get_mut(&mut EXECUTOR).unwrap().interrupt_subscribe(pid.clone(), interrupt_type);
}
}
_ => {
log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers);
}

View file

@ -35,6 +35,7 @@ impl<T: Future<Output = ()> + Send> Process for T {}
pub struct Executor {
tasks: Slab<Task>,
task_queue: Arc<SegQueue<usize>>,
interrupt_lookup: [Option<usize>; u8::MAX as usize],
}
impl Executor {
@ -42,6 +43,7 @@ impl Executor {
Self {
tasks: Slab::new(),
task_queue: Arc::new(SegQueue::new()),
interrupt_lookup: [None; u8::MAX as usize],
}
}
@ -52,19 +54,23 @@ impl Executor {
id
}
pub fn pause(&mut self, id: usize) {
pub fn pause(&self, id: usize) {
if let Some(task) = self.tasks.get(id) {
task.set_paused(true);
}
}
pub fn unpause(&mut self, id: usize) {
pub fn unpause(&self, id: usize) {
if let Some(task) = self.tasks.get(id) {
task.set_paused(false);
self.task_queue.push(id);
}
}
pub fn interrupt_subscribe(&mut self, pid : usize, interrupt_type: u8){
self.interrupt_lookup[interrupt_type as usize] = Some(pid);
}
pub fn run(&mut self) {
let mut task_batch = [0; 32];
loop {
@ -79,7 +85,8 @@ impl Executor {
}
if batch_len == 0 {
break;
//break;
continue;
}
for &(mut id) in &task_batch[..batch_len] {
@ -93,11 +100,26 @@ impl Executor {
if let Poll::Ready(()) = task.poll(&mut cx) {
self.tasks.remove(id);
self.interrupt_lookup.map(|pid|{
if let Some(pid) = pid{
if pid == id {
return None;
}
}
return pid;
});
}
}
}
}
}
pub fn send_interrupt(&self, interrupt : u8){
let id = self.interrupt_lookup[interrupt as usize];
if let Some(id) = id{
self.unpause(id);
}
}
}
struct Task {

View file

@ -3,4 +3,5 @@ subscribe_to_interrupt := fn(interrupt_number: u8): bool {
}
// Pauses execution until the interrupt occures
sleep_until_interrupt := fn(interrupt_number: u8): void {
@eca(6, interrupt_number)
}

View file

@ -0,0 +1,11 @@
[package]
name = "timer_test"
authors = ["Talha Qamar"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -0,0 +1,8 @@
sleep := @use("../../../libraries/stn/src/sleep.hb")
log := @use("../../../libraries/stn/src/log.hb")
main := fn(): int {
log.info("BEFORE\0")
sleep.sleep_until_interrupt(32)
log.info("AFTER\0")
}

View file

@ -28,23 +28,26 @@ resolution = "1024x768x24"
# [boot.limine.ableos.modules.horizon]
# path = "boot:///horizon.hbf"
[boot.limine.ableos.modules.ps2_mouse_driver]
path = "boot:///ps2_mouse_driver.hbf"
# path = "boot:///ps2_mouse_driver.hbf"
# [boot.limine.ableos.modules.ps2_mouse_driver]
# [boot.limine.ableos.modules.ps2_keyboard_driver]
# path = "boot:///ps2_keyboard_driver.hbf"
[boot.limine.ableos.modules.sunset_client]
path = "boot:///sunset_client.hbf"
[boot.limine.ableos.modules.timer_test]
path = "boot:///timer_test.hbf"
[boot.limine.ableos.modules.sunset_client_2]
path = "boot:///sunset_client_2.hbf"
[boot.limine.ableos.modules.sdoom]
path = "boot:///sdoom.hbf"
[boot.limine.ableos.modules.sunset_server]
path = "boot:///sunset_server.hbf"
# [boot.limine.ableos.modules.sunset_client]
# path = "boot:///sunset_client.hbf"
#
# [boot.limine.ableos.modules.sunset_client_2]
# path = "boot:///sunset_client_2.hbf"
#
# [boot.limine.ableos.modules.sdoom]
# path = "boot:///sdoom.hbf"
#
# [boot.limine.ableos.modules.sunset_server]
# path = "boot:///sunset_server.hbf"
# [boot.limine.ableos.modules.pcspkr]
# path = "boot:///pcspkr.hbf"