From 5d152811b213d2f0436489971c024228bee6fcc4 Mon Sep 17 00:00:00 2001 From: kodin Date: Tue, 26 Nov 2024 15:53:50 -0600 Subject: [PATCH] Interrupt Forwarding (#22) Co-authored-by: Talha Qamar Reviewed-on: https://git.ablecorp.us/AbleOS/ableos/pulls/22 Co-authored-by: kodin Co-committed-by: kodin --- kernel/src/arch/x86_64/interrupts.rs | 7 ++++++- kernel/src/holeybytes/ecah.rs | 11 ++++++++++ kernel/src/task.rs | 28 ++++++++++++++++++++++--- sysdata/libraries/stn/src/sleep.hb | 1 + sysdata/programs/timer_test/meta.toml | 11 ++++++++++ sysdata/programs/timer_test/src/main.hb | 8 +++++++ sysdata/system_config.toml | 27 +++++++++++++----------- 7 files changed, 77 insertions(+), 16 deletions(-) create mode 100644 sysdata/programs/timer_test/meta.toml create mode 100644 sysdata/programs/timer_test/src/main.hb diff --git a/kernel/src/arch/x86_64/interrupts.rs b/kernel/src/arch/x86_64/interrupts.rs index 4bd3c8a..28b432c 100644 --- a/kernel/src/arch/x86_64/interrupts.rs +++ b/kernel/src/arch/x86_64/interrupts.rs @@ -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); + } } diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs index a34f683..b1561f9 100644 --- a/kernel/src/holeybytes/ecah.rs +++ b/kernel/src/holeybytes/ecah.rs @@ -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::(); + info!("Interrupt subscribled: {}", interrupt_type); + unsafe{ + EXECUTOR.pause(pid.clone()); + LazyCell::::get_mut(&mut EXECUTOR).unwrap().interrupt_subscribe(pid.clone(), interrupt_type); + } + } _ => { log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers); } diff --git a/kernel/src/task.rs b/kernel/src/task.rs index 01c6688..c79140f 100644 --- a/kernel/src/task.rs +++ b/kernel/src/task.rs @@ -35,6 +35,7 @@ impl + Send> Process for T {} pub struct Executor { tasks: Slab, task_queue: Arc>, + interrupt_lookup: [Option; 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 { diff --git a/sysdata/libraries/stn/src/sleep.hb b/sysdata/libraries/stn/src/sleep.hb index d323267..5aeaf14 100644 --- a/sysdata/libraries/stn/src/sleep.hb +++ b/sysdata/libraries/stn/src/sleep.hb @@ -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) } \ No newline at end of file diff --git a/sysdata/programs/timer_test/meta.toml b/sysdata/programs/timer_test/meta.toml new file mode 100644 index 0000000..c05908d --- /dev/null +++ b/sysdata/programs/timer_test/meta.toml @@ -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" diff --git a/sysdata/programs/timer_test/src/main.hb b/sysdata/programs/timer_test/src/main.hb new file mode 100644 index 0000000..b2142ea --- /dev/null +++ b/sysdata/programs/timer_test/src/main.hb @@ -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") +} \ No newline at end of file diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml index a63f170..34ab790 100644 --- a/sysdata/system_config.toml +++ b/sysdata/system_config.toml @@ -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"