keos/task.rs
1//! Task trait for interact with user process.
2
3use crate::thread::kill_current_thread;
4pub use abyss::x86_64::interrupt::PFErrorCode;
5use abyss::{
6 addressing::{Pa, Va},
7 interrupt::Registers,
8};
9use core::ops::Range;
10
11/// Represents a **task** executed by a thread.
12///
13/// This trait defines core functionalities required for handling event
14/// triggered by user process, such as **system calls**, **page faults**.
15pub trait Task {
16 /// Handles a **system call** triggered by the user program.
17 ///
18 /// - The `registers` parameter contains the state of the CPU registers at
19 /// the time of the system call.
20 /// - Implementations of this function should parse the system call
21 /// arguments, execute the corresponding operation, and store the result
22 /// back in `registers`.
23 fn syscall(&mut self, registers: &mut Registers);
24
25 /// Handles a **page fault** that occurs when accessing an unmapped memory
26 /// page.
27 ///
28 /// - The `ec` parameter provides information about the cause of the page
29 /// fault.
30 fn page_fault(&mut self, ec: PFErrorCode, cr2: Va) {
31 if (ec & PFErrorCode::USER) == PFErrorCode::USER {
32 println!(
33 "[ERROR] Page fault occurs by {:?} [0x{:x}]. Killing thread...",
34 if !ec.contains(PFErrorCode::PRESENT) {
35 "accessing non-present page"
36 } else if ec.contains(PFErrorCode::INSTRCUTION_FETCH) {
37 "executing non-executable page"
38 } else if ec.contains(PFErrorCode::WRITE_ACCESS) {
39 "writing to a read-only page"
40 } else {
41 "other protection violation on page"
42 },
43 cr2.into_usize(),
44 );
45 kill_current_thread();
46 } else {
47 panic!(
48 "Unexpected page fault in Kernel at {:?} because of {:?}",
49 cr2, ec
50 );
51 }
52 }
53
54 /// Validates a given **memory address range** before use.
55 ///
56 /// - `addr`: The range of virtual addresses being accessed.
57 /// - `is_write`: Indicates whether the memory is being **read** (`false`)
58 /// or **written to** (`true`).
59 /// - Returns `true` if the memory range is valid, or an appropriate
60 /// `KernelError` otherwise.
61 #[allow(unused_variables)]
62 fn access_ok(&self, addr: Range<Va>, is_write: bool) -> bool {
63 // Currently, check only addr is null pointer.
64 addr.start.into_usize() != 0
65 }
66
67 /// Run a closure with physical address of the page table.
68 fn with_page_table_pa(&self, _f: &fn(Pa)) {}
69}
70
71impl Task for () {
72 fn syscall(&mut self, _registers: &mut Registers) {
73 unreachable!()
74 }
75}