lifeblood_os/liblbos/src/ktask.rs
2025-09-08 20:56:44 -07:00

310 lines
No EOL
9.4 KiB
Rust

#[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
}