#[repr(u16)] pub enum KTaskRequestType { DoNothing = 0, /// prints a message to the terminal greeting the user (: SayHi = 1, /// readies the filesystem for use /// takes a FileSystem struct as defined in crate::fs, this struct contains unknown members. /// that depend on what hbd filesystem the kernel was compiled with, but will always be 32 bytes. /// it's probably best to stack allocate it in the calling procees. /// 0 indicates success, 1 indicates failure FSOpen = 2, /// takes a string, interprets it as an absolute filesystem path, and opens it as a directory reader. /// requires a previous call to FSOpen. /// 0 indicates success, /// 1 = directory not found /// 2 = invalid record (i.e. you tried to open a file as a directory) /// 3 = user error (you probably didn't prefix the path with '/') FSOpenDir = 3, /// takes a directory reader and an empty record struct, and reads one record from the directory into it. /// requires a previous call to FSOpenDir /// 0 = success /// 1 = end of directory /// 2 = other error FSReadDir = 4, /// takes a file record and an empty file reader struct, and readies the file reader struct for reading /// requires a previous call to fsopen /// 0 = success /// 1 = failure FSOpenFile = 5, /// reads data from the file reader into the provided buffer, until either the buffer is full or the file is at the end. /// requires a previous call to FSOpenFile /// returns success on all calls, including the last one; if EOF is reached, the buffer was not touched /// 0 = success /// 1 = end of file /// 2 = other error FSReadFile = 6, /// seeks forward N sectors in the file. /// requires a previous call to FSOpenFile /// 0 = success /// 1 = failure (i.e. cannot seek due to EOF) FSSeek = 7, /// given a DDI file buffer, loads the file into memory and returns the required information to execute it /// after loading, you can free the file buffer without concern /// 0 = success /// 1 = failure LoadDDIFile = 8, } #[repr(C)] pub struct KTaskRequest { pub req: u16, pub replyto: u8, pub retval: u32, } #[repr(C)] pub struct KTaskFSOpenRequest { pub base: KTaskRequest, pub fs: *mut crate::fs::FileSystem, } #[repr(C)] pub struct KTaskFSOpenDirRequest { pub base: KTaskRequest, pub fs: *const crate::fs::FileSystem, pub dir: *mut crate::fs::DirectoryReader, pub path: *const u8, pub pathlen: u32, } #[repr(C)] pub struct KTaskFSReadDirRequest { pub base: KTaskRequest, pub fs: *const crate::fs::FileSystem, pub dir: *mut crate::fs::DirectoryReader, pub record: *mut crate::fs::Record, } #[repr(C)] pub struct KTaskFSOpenFileRequest { pub base: KTaskRequest, pub fs: *const crate::fs::FileSystem, pub record: *const crate::fs::Record, pub reader: *mut crate::fs::FileReader, } #[repr(C)] pub struct KTaskFSReadFileRequest { pub base: KTaskRequest, pub fs: *const crate::fs::FileSystem, pub reader: *mut crate::fs::FileReader, pub buffer: *mut u8, pub bufferlen: u32, } #[repr(C)] pub struct KTaskFSSeek { pub base: KTaskRequest, pub fs: *const crate::fs::FileSystem, pub reader: *mut crate::fs::FileReader, pub sectors: u32, } #[repr(C)] pub struct KTaskLoadDDIFile { pub base: KTaskRequest, pub file_buf_pointer: usize, pub file_buf_len: usize, pub task_setup_ptr: usize, } pub fn request_type_from_req(req: u16) -> KTaskRequestType { match req { 0 => KTaskRequestType::DoNothing, 1 => KTaskRequestType::SayHi, 2 => KTaskRequestType::FSOpen, 3 => KTaskRequestType::FSOpenDir, 4 => KTaskRequestType::FSReadDir, 5 => KTaskRequestType::FSOpenFile, 6 => KTaskRequestType::FSReadFile, 7 => KTaskRequestType::FSSeek, 8 => KTaskRequestType::LoadDDIFile, _ => KTaskRequestType::DoNothing, } } pub fn query_ktask(req: usize) { crate::syscalls::send_notification(0, req); crate::syscalls::wait_for_notif_ack(0); let tmp = crate::syscalls::wait_for_notification(); if tmp != req { crate::syscalls::write_terminal(b"ktask failed to respond properly!\n"); } } pub fn ktask_sayhi() { let ci = crate::syscalls::current_task(); let req = crate::syscalls::alloc_blocks(1); { let req = unsafe { &mut *(req as *mut KTaskRequest) }; req.req = KTaskRequestType::SayHi as u16; req.replyto = ci; } query_ktask(req); crate::syscalls::free_blocks(req, 1); } pub fn ktask_fsopen(fs: &mut crate::fs::FileSystem) -> usize { let ci = crate::syscalls::current_task(); let req = crate::syscalls::alloc_blocks(1); { let req = unsafe { &mut *(req as *mut KTaskFSOpenRequest) }; req.base.req = KTaskRequestType::FSOpen as u16; req.base.replyto = ci; req.fs = fs as *mut _; } query_ktask(req); let retval = { let req = unsafe { &mut *(req as *mut KTaskFSOpenRequest) }; req.base.retval }; crate::syscalls::free_blocks(req, 1); retval as usize } pub fn ktask_fsopendir( fs: &crate::fs::FileSystem, dir: &mut crate::fs::DirectoryReader, path: &[u8], ) -> usize { let ci = crate::syscalls::current_task(); let req = crate::syscalls::alloc_blocks(1); { let req = unsafe { &mut *(req as *mut KTaskFSOpenDirRequest) }; req.base.req = KTaskRequestType::FSOpenDir as u16; req.base.replyto = ci; req.fs = fs as *const _; req.dir = dir as *mut _; req.path = path.as_ptr(); req.pathlen = path.len() as u32; } query_ktask(req); let retval = { let req = unsafe { &mut *(req as *mut KTaskFSOpenDirRequest) }; req.base.retval }; crate::syscalls::free_blocks(req, 1); retval as usize } pub fn ktask_fsreaddir( fs: &crate::fs::FileSystem, dir: &mut crate::fs::DirectoryReader, record: &mut crate::fs::Record, ) -> usize { let ci = crate::syscalls::current_task(); let req = crate::syscalls::alloc_blocks(1); { let req = unsafe { &mut *(req as *mut KTaskFSReadDirRequest) }; req.base.req = KTaskRequestType::FSReadDir as u16; req.base.replyto = ci; req.fs = fs as *const _; req.dir = dir as *mut _; req.record = record as *mut _; } query_ktask(req); let retval = { let req = unsafe { &mut *(req as *mut KTaskFSReadDirRequest) }; req.base.retval }; crate::syscalls::free_blocks(req, 1); retval as usize } pub fn ktask_fsopenfile( fs: &crate::fs::FileSystem, record: &crate::fs::Record, reader: &mut crate::fs::FileReader, ) -> usize { let ci = crate::syscalls::current_task(); let req = crate::syscalls::alloc_blocks(1); { let req = unsafe { &mut *(req as *mut KTaskFSOpenFileRequest) }; req.base.req = KTaskRequestType::FSOpenFile as u16; req.base.replyto = ci; req.fs = fs as *const _; req.record = record as *const _; req.reader = reader as *mut _; } query_ktask(req); let retval = { let req = unsafe { &mut *(req as *mut KTaskFSOpenFileRequest) }; req.base.retval }; crate::syscalls::free_blocks(req, 1); retval as usize } pub fn ktask_fsreadfile( fs: &crate::fs::FileSystem, reader: &mut crate::fs::FileReader, buffer: &mut [u8], ) -> usize { let ci = crate::syscalls::current_task(); let req = crate::syscalls::alloc_blocks(1); { let req = unsafe { &mut *(req as *mut KTaskFSReadFileRequest) }; req.base.req = KTaskRequestType::FSReadFile as u16; req.base.replyto = ci; req.fs = fs as *const _; req.reader = reader as *mut _; req.buffer = buffer.as_mut_ptr(); req.bufferlen = buffer.len() as u32; } query_ktask(req); let retval = { let req = unsafe { &mut *(req as *mut KTaskFSReadFileRequest) }; req.base.retval }; crate::syscalls::free_blocks(req, 1); retval as usize } pub fn ktask_fsseek( fs: &crate::fs::FileSystem, reader: &mut crate::fs::FileReader, sectors: u32, ) -> usize { let ci = crate::syscalls::current_task(); let req = crate::syscalls::alloc_blocks(1); { let req = unsafe { &mut *(req as *mut KTaskFSSeek) }; req.base.req = KTaskRequestType::FSSeek as u16; req.base.replyto = ci; req.fs = fs as *const _; req.reader = reader as *mut _; req.sectors = sectors; } query_ktask(req); let retval = { let req = unsafe { &mut *(req as *mut KTaskFSSeek) }; req.base.retval }; crate::syscalls::free_blocks(req, 1); retval as usize } pub fn ktask_loadddifile( file_buf_pointer: usize, file_buf_len: usize, task_setup_ptr: usize, ) -> usize { let ci = crate::syscalls::current_task(); let req = crate::syscalls::alloc_blocks(1); { let req = unsafe { &mut *(req as *mut KTaskLoadDDIFile) }; req.base.req = KTaskRequestType::LoadDDIFile as u16; req.base.replyto = ci; req.file_buf_pointer = file_buf_pointer; req.file_buf_len = file_buf_len; req.task_setup_ptr = task_setup_ptr; } query_ktask(req); let retval = { let req = unsafe { &mut *(req as *mut KTaskLoadDDIFile) }; req.base.retval }; crate::syscalls::free_blocks(req, 1); retval as usize }