Interrupt Forwarding #22
|
@ -62,7 +62,7 @@ extern "x86-interrupt" fn page_fault(
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
|
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
|
||||||
// interrupt(Interrupt::Timer);
|
interrupt(Interrupt::Timer);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
LAPIC.end_of_interrupt();
|
LAPIC.end_of_interrupt();
|
||||||
|
@ -85,6 +85,7 @@ extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
|
||||||
|
|
||||||
fn interrupt(interrupt_type: Interrupt) {
|
fn interrupt(interrupt_type: Interrupt) {
|
||||||
use crate::arch::INTERRUPT_LIST;
|
use crate::arch::INTERRUPT_LIST;
|
||||||
|
use crate::kmain::EXECUTOR;
|
||||||
let il = INTERRUPT_LIST.lock();
|
let il = INTERRUPT_LIST.lock();
|
||||||
let val = il.list.get(&interrupt_type).unwrap();
|
let val = il.list.get(&interrupt_type).unwrap();
|
||||||
|
|
||||||
|
@ -107,4 +108,8 @@ fn interrupt(interrupt_type: Interrupt) {
|
||||||
|
|
||||||
// log::info!("{}", buffer);
|
// log::info!("{}", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe{
|
||||||
|
EXECUTOR.send_interrupt(interrupt_type as u8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! Environment call handling routines
|
//! Environment call handling routines
|
||||||
|
|
||||||
|
use log::log;
|
||||||
|
|
||||||
use {alloc::boxed::Box, core::cell::LazyCell, hbvm::mem::Address};
|
use {alloc::boxed::Box, core::cell::LazyCell, hbvm::mem::Address};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -242,6 +244,15 @@ pub fn handler(vm: &mut Vm, pid: &usize) {
|
||||||
vm.registers[3] = x
|
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);
|
log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ impl<T: Future<Output = ()> + Send> Process for T {}
|
||||||
pub struct Executor {
|
pub struct Executor {
|
||||||
tasks: Slab<Task>,
|
tasks: Slab<Task>,
|
||||||
task_queue: Arc<SegQueue<usize>>,
|
task_queue: Arc<SegQueue<usize>>,
|
||||||
|
interrupt_lookup: [Option<usize>; u8::MAX as usize],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Executor {
|
impl Executor {
|
||||||
|
@ -42,6 +43,7 @@ impl Executor {
|
||||||
Self {
|
Self {
|
||||||
tasks: Slab::new(),
|
tasks: Slab::new(),
|
||||||
task_queue: Arc::new(SegQueue::new()),
|
task_queue: Arc::new(SegQueue::new()),
|
||||||
|
interrupt_lookup: [None; u8::MAX as usize],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,19 +54,23 @@ impl Executor {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pause(&mut self, id: usize) {
|
pub fn pause(&self, id: usize) {
|
||||||
if let Some(task) = self.tasks.get(id) {
|
if let Some(task) = self.tasks.get(id) {
|
||||||
task.set_paused(true);
|
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) {
|
if let Some(task) = self.tasks.get(id) {
|
||||||
task.set_paused(false);
|
task.set_paused(false);
|
||||||
self.task_queue.push(id);
|
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) {
|
pub fn run(&mut self) {
|
||||||
let mut task_batch = [0; 32];
|
let mut task_batch = [0; 32];
|
||||||
loop {
|
loop {
|
||||||
|
@ -79,7 +85,8 @@ impl Executor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if batch_len == 0 {
|
if batch_len == 0 {
|
||||||
break;
|
//break;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for &(mut id) in &task_batch[..batch_len] {
|
for &(mut id) in &task_batch[..batch_len] {
|
||||||
|
@ -93,11 +100,26 @@ impl Executor {
|
||||||
|
|
||||||
if let Poll::Ready(()) = task.poll(&mut cx) {
|
if let Poll::Ready(()) = task.poll(&mut cx) {
|
||||||
self.tasks.remove(id);
|
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 {
|
struct Task {
|
||||||
|
|
|
@ -3,4 +3,5 @@ subscribe_to_interrupt := fn(interrupt_number: u8): bool {
|
||||||
}
|
}
|
||||||
// Pauses execution until the interrupt occures
|
// Pauses execution until the interrupt occures
|
||||||
sleep_until_interrupt := fn(interrupt_number: u8): void {
|
sleep_until_interrupt := fn(interrupt_number: u8): void {
|
||||||
|
@eca(6, interrupt_number)
|
||||||
}
|
}
|
11
sysdata/programs/timer_test/meta.toml
Normal file
11
sysdata/programs/timer_test/meta.toml
Normal 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"
|
8
sysdata/programs/timer_test/src/main.hb
Normal file
8
sysdata/programs/timer_test/src/main.hb
Normal 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")
|
||||||
|
}
|
|
@ -28,23 +28,26 @@ resolution = "1024x768x24"
|
||||||
# [boot.limine.ableos.modules.horizon]
|
# [boot.limine.ableos.modules.horizon]
|
||||||
# path = "boot:///horizon.hbf"
|
# 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]
|
# [boot.limine.ableos.modules.ps2_keyboard_driver]
|
||||||
# path = "boot:///ps2_keyboard_driver.hbf"
|
# path = "boot:///ps2_keyboard_driver.hbf"
|
||||||
|
|
||||||
[boot.limine.ableos.modules.sunset_client]
|
[boot.limine.ableos.modules.timer_test]
|
||||||
path = "boot:///sunset_client.hbf"
|
path = "boot:///timer_test.hbf"
|
||||||
|
|
||||||
[boot.limine.ableos.modules.sunset_client_2]
|
# [boot.limine.ableos.modules.sunset_client]
|
||||||
path = "boot:///sunset_client_2.hbf"
|
# path = "boot:///sunset_client.hbf"
|
||||||
|
#
|
||||||
[boot.limine.ableos.modules.sdoom]
|
# [boot.limine.ableos.modules.sunset_client_2]
|
||||||
path = "boot:///sdoom.hbf"
|
# path = "boot:///sunset_client_2.hbf"
|
||||||
|
#
|
||||||
[boot.limine.ableos.modules.sunset_server]
|
# [boot.limine.ableos.modules.sdoom]
|
||||||
path = "boot:///sunset_server.hbf"
|
# path = "boot:///sdoom.hbf"
|
||||||
|
#
|
||||||
|
# [boot.limine.ableos.modules.sunset_server]
|
||||||
|
# path = "boot:///sunset_server.hbf"
|
||||||
|
|
||||||
# [boot.limine.ableos.modules.pcspkr]
|
# [boot.limine.ableos.modules.pcspkr]
|
||||||
# path = "boot:///pcspkr.hbf"
|
# path = "boot:///pcspkr.hbf"
|
||||||
|
|
Loading…
Reference in a new issue