Переглянути джерело

trap: introduce Breakpoint fault type

TODO: hide changes to the program counter in the HAL crate.

Signed-off-by: greatbridf <greatbridf@icloud.com>
greatbridf 5 місяців тому
батько
коміт
a622172587

+ 1 - 0
crates/eonix_hal/eonix_hal_traits/src/trap.rs

@@ -66,6 +66,7 @@ where
 {
     Syscall { no: usize, args: [usize; 6] },
     Fault(Fault),
+    Breakpoint,
     Irq { callback: FIrq },
     Timer { callback: FTimer },
 }

+ 1 - 0
crates/eonix_hal/src/arch/loongarch64/trap/trap_context.rs

@@ -173,6 +173,7 @@ impl RawTrapContext for TrapContext {
                 | Exception::MemoryAccessAddressError
                 | Exception::PagePrivilegeIllegal,
             ) => TrapType::Fault(Fault::BadAccess),
+            Trap::Exception(Exception::Breakpoint) => TrapType::Breakpoint,
             Trap::Exception(Exception::InstructionNotExist) => TrapType::Fault(Fault::InvalidOp),
             Trap::Exception(Exception::Syscall) => TrapType::Syscall {
                 no: self.syscall_no(),

+ 1 - 0
crates/eonix_hal/src/arch/riscv64/trap/trap_context.rs

@@ -166,6 +166,7 @@ impl RawTrapContext for TrapContext {
             }
             Trap::Exception(e) => {
                 match Exception::from_number(e).unwrap() {
+                    Exception::Breakpoint => TrapType::Breakpoint,
                     Exception::InstructionMisaligned
                     | Exception::LoadMisaligned
                     | Exception::InstructionFault

+ 1 - 0
src/kernel/interrupt.rs

@@ -48,6 +48,7 @@ pub fn default_fault_handler(fault_type: Fault, trap_ctx: &mut TrapContext) {
 pub fn interrupt_handler(trap_ctx: &mut TrapContext) {
     match trap_ctx.trap_type() {
         TrapType::Syscall { no, .. } => unreachable!("Syscall {} in kernel space.", no),
+        TrapType::Breakpoint => unreachable!("Breakpoint in kernel space."),
         TrapType::Fault(fault) => default_fault_handler(fault, trap_ctx),
         TrapType::Irq { callback } => callback(default_irq_handler),
         TrapType::Timer { callback } => callback(timer_interrupt),

+ 14 - 19
src/kernel/task.rs

@@ -94,7 +94,6 @@ where
     use core::task::Context;
     use core::task::Poll;
     use core::task::Waker;
-    use eonix_hal::traits::fault::Fault;
     use eonix_hal::traits::trap::RawTrapContext;
     use eonix_hal::traits::trap::TrapReturn;
     use eonix_hal::traits::trap::TrapType;
@@ -183,24 +182,7 @@ where
 
         match trap_ctx.trap_type() {
             TrapType::Syscall { .. } => {}
-            TrapType::Fault(fault) => {
-                // Breakpoint
-                if let Fault::Unknown(3) = &fault {
-                    if let Some(output) = output.get_mut().take() {
-                        break output;
-                    } else {
-                        wait_for_wakeups().await;
-                    }
-
-                    #[cfg(target_arch = "riscv64")]
-                    trap_ctx.set_program_counter(trap_ctx.get_program_counter() + 2);
-
-                    #[cfg(target_arch = "loongarch64")]
-                    trap_ctx.set_program_counter(trap_ctx.get_program_counter() + 4);
-                } else {
-                    default_fault_handler(fault, &mut trap_ctx)
-                }
-            }
+            TrapType::Fault(fault) => default_fault_handler(fault, &mut trap_ctx),
             TrapType::Irq { callback } => callback(default_irq_handler),
             TrapType::Timer { callback } => {
                 callback(timer_interrupt);
@@ -209,6 +191,19 @@ where
                     yield_now().await;
                 }
             }
+            TrapType::Breakpoint => {
+                if let Some(output) = output.get_mut().take() {
+                    break output;
+                } else {
+                    wait_for_wakeups().await;
+                }
+
+                #[cfg(target_arch = "riscv64")]
+                trap_ctx.set_program_counter(trap_ctx.get_program_counter() + 2);
+
+                #[cfg(target_arch = "loongarch64")]
+                trap_ctx.set_program_counter(trap_ctx.get_program_counter() + 4);
+            }
         }
     }
 }

+ 1 - 0
src/kernel/task/thread.rs

@@ -391,6 +391,7 @@ impl Thread {
                     self.signal_list.raise(Signal::SIGILL);
                 }
                 TrapType::Fault(Fault::Unknown(_)) => unimplemented!("Unhandled fault"),
+                TrapType::Breakpoint => unimplemented!("Breakpoint in user space"),
                 TrapType::Irq { callback } => callback(default_irq_handler),
                 TrapType::Timer { callback } => {
                     callback(timer_interrupt);