Event system

This commit is contained in:
Gvidas Juknevičius 2024-06-12 02:18:10 +03:00
parent 1b2dd2bfbe
commit 638bfb2d5c
Signed by: MCorange
GPG Key ID: 12B1346D720B7FBB
8 changed files with 103 additions and 32 deletions

View File

@ -1,12 +1,63 @@
use core::mem::discriminant;
use lazy_static::lazy_static;
#[macro_use]
mod types;
use spin::Mutex;
pub use types::*;
const MAX_EVENT_LISTENERS: usize = 255;
pub struct KernelEventHandler {
lazy_static!(
pub static ref EVENTMAN: Mutex<EventManager> = Mutex::new(EventManager::new());
);
pub struct EventManager {
listeners: [Option<EventManagerEntry>; MAX_EVENT_LISTENERS],
listener_count: usize,
}
type EventListenerFunc = fn(ev: &Event) -> Result<(), ()>;
pub struct EventManagerEntry {
pub func: EventListenerFunc,
pub typ: Event
}
const ARRAY_REPEAT_VALUE: Option<EventManagerEntry> = None;
impl EventManager {
pub fn new() -> Self {
Self {
listeners: [ARRAY_REPEAT_VALUE; MAX_EVENT_LISTENERS],
listener_count: 0
}
}
pub fn dispatch(&self, ev: &Event){
for listener in &self.listeners {
if let Some(l) = listener {
if discriminant(ev) == discriminant(&l.typ) {
// TODO: Do something with the result
let _ = (l.func)(ev);
}
}
}
}
pub fn add_listener(&mut self, typ: Event, func: EventListenerFunc) {
self.listeners[self.listener_count] = Some(EventManagerEntry {
func, typ
})
}
#[allow(dead_code)]
pub fn remove_listener(&mut self, _: &str) {
todo!()
}
}
impl KernelEventHandler {
}

View File

@ -0,0 +1,19 @@
use pc_keyboard::DecodedKey;
#[allow(dead_code)]
#[derive(Debug)]
pub enum Event {
TimerInterrupt(Option<usize>), // trash unused value
Ps2KeyPress(Option<DecodedKey>)
}
#[macro_export]
macro_rules! get_event_value {
($typ:pat, $ev:expr) => {
match $ev {
$typ(v) => v.unwrap(),
_ => panic!("Bad event value")
}
};
}

View File

@ -1,5 +1,5 @@
use x86_64::structures::idt::{InterruptStackFrame, PageFaultErrorCode};
use crate::interrupts::InterruptIndex;
use crate::{events::EVENTMAN, interrupts::InterruptIndex};
mod ps2_keyboard;
@ -12,6 +12,7 @@ pub extern "x86-interrupt" fn breakpoint(sf: InterruptStackFrame){
pub extern "x86-interrupt" fn timer_interrupt(_: InterruptStackFrame){
//log::debug!("INT: TIMER\n{:#?}", sf);
// print!(".");
EVENTMAN.lock().dispatch(&crate::events::Event::TimerInterrupt(None));
unsafe {
super::PICS.lock()
.notify_end_of_interrupt(InterruptIndex::Timer as u8);

View File

@ -1,6 +1,9 @@
use pc_keyboard::DecodedKey;
use x86_64::structures::idt::InterruptStackFrame;
use crate::interrupts::PICS;
use crate::{events::EVENTMAN, interrupts::PICS};
pub struct Ps2KbPressEvent(DecodedKey);
pub extern "x86-interrupt" fn ps2_kb_int(_sf: InterruptStackFrame){
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
@ -20,12 +23,7 @@ pub extern "x86-interrupt" fn ps2_kb_int(_sf: InterruptStackFrame){
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) {
if false {
match key {
DecodedKey::Unicode(character) => print!("{}", character),
DecodedKey::RawKey(key) => print!("{:?}", key),
}
}
EVENTMAN.lock().dispatch(&crate::events::Event::Ps2KeyPress(Some(key)));
}
}
unsafe {

View File

@ -1,5 +1,6 @@
use pic8259::ChainedPics;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
use x86_64::structures::idt::InterruptDescriptorTable;
mod handlers;

View File

@ -1,17 +1,18 @@
#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
#![feature(associated_type_defaults)]
use multiboot2::BootInformationHeader;
use x86_64::registers::control::Cr3;
use events::EVENTMAN;
use crate::mem::FrameAllocator;
use crate::events::Event;
#[macro_use]
mod logger;
mod interrupts;
mod gdt;
mod utils;
#[macro_use]
mod events;
mod mem;
@ -24,15 +25,16 @@ extern "C" fn kmain(mb2_info_addr: usize) -> ! {
gdt::init();
interrupts::init_idt();
let mem_info = mem::MemInfo::load(mb2_info_addr);
let mut alloc = mem::area_frame_alloc::AreaFrameAllocator::new(mem_info);
for i in 0.. {
if let None = alloc.allocate_frame() {
println!("allocated {} frames", i);
break;
}
}
let mut _alloc = mem::area_frame_alloc::AreaFrameAllocator::new(mem_info);
EVENTMAN.lock().add_listener(events::Event::Ps2KeyPress(None), |k| {
let Event::Ps2KeyPress(v) = k else {panic!()};
log::debug!("Keypress event received! ({:?})", v.unwrap());
Ok(())
});
// let (level_4_page_table, _) = Cr3::read();
// println!("Level 4 page table at: {:?}", level_4_page_table.start_address());

View File

@ -1,5 +1,3 @@
use core::slice::Iter;
use super::{Frame, FrameAllocator, MemInfo, MemoryAreaIter};
use multiboot2::MemoryArea;

View File

@ -1,6 +1,6 @@
use core::{alloc::{GlobalAlloc, Layout}, ops::Deref};
use core::alloc::{GlobalAlloc, Layout};
use multiboot2::{BootInformation, BootInformationHeader, MemoryArea, MemoryAreaType, MemoryMapTag, TagTrait};
use multiboot2::{BootInformationHeader, MemoryArea, MemoryAreaType, MemoryMapTag, TagTrait};
pub mod area_frame_alloc;
@ -8,8 +8,8 @@ pub mod area_frame_alloc;
static GLOBAL_ALLOCATOR: DummyAlloc = DummyAlloc;
pub struct DummyAlloc;
unsafe impl GlobalAlloc for DummyAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 0 as *mut u8 }
unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) {}
unsafe fn alloc(&self, _: Layout) -> *mut u8 { 0 as *mut u8 }
unsafe fn dealloc(&self, _ptr: *mut u8, _: Layout) {}
}
pub const PAGE_SIZE: usize = 4096;
@ -26,6 +26,7 @@ impl Frame {
}
}
#[allow(dead_code)]
pub trait FrameAllocator {
fn allocate_frame(&mut self) -> Option<Frame>;
fn deallocate_frame(&mut self, frame: Frame);
@ -83,7 +84,7 @@ impl MemInfo {
let boot_info = unsafe {
multiboot2::BootInformation::load(mb_ptr as *const BootInformationHeader).unwrap()
};
let mmap_tag = boot_info.memory_map_tag().unwrap().clone();
let mmap_tag = boot_info.memory_map_tag().unwrap();
// log::debug!("Memory areas:");
// for area in mmap_tag.memory_areas() {