fn determine_stop_reason(&mut self, reason: KCoreStopReason) -> Option<ThreadStopReason<u64>> {
        match reason {
            KCoreStopReason::ConnectionInterrupt => Some(ThreadStopReason::Signal(Signal::SIGTRAP)),
            KCoreStopReason::BreakpointInterrupt => {
                unimplemented!("Breakpoint interrupt not implemented");
                //Some(ThreadStopReason::SwBreak(NonZeroUsize::new(1).unwrap()))
            }
            KCoreStopReason::DebugInterrupt => {
                // Safety: We are in the kernel so we can access dr6.
                let mut dr6 = unsafe { debugregs::dr6() };

                let bp = if dr6.contains(debugregs::Dr6::B0) {
                    dr6.remove(debugregs::Dr6::B0);
                    self.hw_break_points[0]
                } else if dr6.contains(debugregs::Dr6::B1) {
                    dr6.remove(debugregs::Dr6::B1);
                    self.hw_break_points[1]
                } else if dr6.contains(debugregs::Dr6::B2) {
                    dr6.remove(debugregs::Dr6::B2);
                    self.hw_break_points[2]
                } else if dr6.contains(debugregs::Dr6::B3) {
                    dr6.remove(debugregs::Dr6::B3);
                    self.hw_break_points[3]
                } else {
                    // If None, we are either single-stepping (debugregs::Dr6::BS,
                    // handled below) or are at the start of the kernel (no
                    // breakpoints were set yet)
                    None
                };

                // Map things to a gdbstub stop reason:
                let stop: Option<ThreadStopReason<u64>> = if let Some(BreakState(
                    _va,
                    BreakType::Breakpoint,
                    BreakRequest::Hardware,
                )) = bp
                {
                    Some(ThreadStopReason::HwBreak(NonZeroUsize::new(1).unwrap()))
                } else if let Some(BreakState(_va, BreakType::Breakpoint, BreakRequest::Software)) =
                    bp
                {
                    Some(ThreadStopReason::SwBreak(NonZeroUsize::new(1).unwrap()))
                } else if let Some(BreakState(
                    va,
                    BreakType::Watchpoint(kind),
                    BreakRequest::Hardware,
                )) = bp
                {
                    Some(ThreadStopReason::Watch {
                        tid: NonZeroUsize::new(1).unwrap(),
                        kind,
                        addr: va.as_u64(),
                    })
                } else if let Some(BreakState(
                    _va,
                    BreakType::Watchpoint(_kind),
                    BreakRequest::Software,
                )) = bp
                {
                    unimplemented!("Shouldn't have ever set a software watchpoint!")
                } else if dr6.contains(debugregs::Dr6::BS) {
                    // When the BS flag is set, any of the other debug status bits also may be set.
                    dr6.remove(debugregs::Dr6::BS);
                    Some(ThreadStopReason::DoneStep)
                } else {
                    None
                };

                // Sanity check that we indeed handled all bits in dr6 (except RTM
                // which isn't a condition):
                if !dr6.difference(debugregs::Dr6::RTM).is_empty() {
                    // The code assumes that only one BP (or BS) condition gets set
                    // for a single IRQ. If multiple conditions can trigger per IRQ,
                    // we need to rethink this code.
                    //
                    // Maybe we have to handle every potential flag in dr6 in some
                    // loop one after the other, or ignore some? For now, we just
                    // log and then clear/ignore the unhandled bits:
                    error!("Unhandled/ignored these conditions in dr6: {:?}", dr6);
                    dr6 = debugregs::Dr6::empty(); // This will clear RTM (we don't use this atm.)
                }

                unsafe { debugregs::dr6_write(dr6) };

                stop
            }
        }
    }
/// Figures out why a core got a debug interrupt by looking through the
/// hardware debug register and reading which one was hit.
///
// Also does some additional stuff like re-enabling the breakpoints.
Figures out why a core got a debug interrupt by looking through the
hardware debug register and reading which one was hit.

Also does some additional stuff like re-enabling the breakpoints.
Figures out why a core got a debug interrupt by looking through the hardware debug register and reading which one was hit . Also does some additional stuff like re - enabling the breakpoints .
fn determine_stop_reason(&mut self, reason: KCoreStopReason) -> Option<ThreadStopReason<u64>> {
        match reason {
            KCoreStopReason::ConnectionInterrupt => Some(ThreadStopReason::Signal(Signal::SIGTRAP)),
            KCoreStopReason::BreakpointInterrupt => {
                unimplemented!("Breakpoint interrupt not implemented");
                //Some(ThreadStopReason::SwBreak(NonZeroUsize::new(1).unwrap()))
            }
            KCoreStopReason::DebugInterrupt => {
                // Safety: We are in the kernel so we can access dr6.
                let mut dr6 = unsafe { debugregs::dr6() };
                let bp = if dr6.contains(debugregs::Dr6::B0) {
                    dr6.remove(debugregs::Dr6::B0);
                    self.hw_break_points[0]
                } else if dr6.contains(debugregs::Dr6::B1) {
                    dr6.remove(debugregs::Dr6::B1);
                    self.hw_break_points[1]
                } else if dr6.contains(debugregs::Dr6::B2) {
                    dr6.remove(debugregs::Dr6::B2);
                    self.hw_break_points[2]
                } else if dr6.contains(debugregs::Dr6::B3) {
                    dr6.remove(debugregs::Dr6::B3);
                    self.hw_break_points[3]
                } else {
                    // If None, we are either single-stepping (debugregs::Dr6::BS,
                    // handled below) or are at the start of the kernel (no
                    // breakpoints were set yet)
                    None
                };
                // Map things to a gdbstub stop reason:
                let stop: Option<ThreadStopReason<u64>> = if let Some(BreakState(
                    _va,
                    BreakType::Breakpoint,
                    BreakRequest::Hardware,
                )) = bp
                {
                    Some(ThreadStopReason::HwBreak(NonZeroUsize::new(1).unwrap()))
                } else if let Some(BreakState(_va, BreakType::Breakpoint, BreakRequest::Software)) =
                    bp
                {
                    Some(ThreadStopReason::SwBreak(NonZeroUsize::new(1).unwrap()))
                } else if let Some(BreakState(
                    va,
                    BreakType::Watchpoint(kind),
                    BreakRequest::Hardware,
                )) = bp
                {
                    Some(ThreadStopReason::Watch {
                        tid: NonZeroUsize::new(1).unwrap(),
                        kind,
                        addr: va.as_u64(),
                    })
                } else if let Some(BreakState(
                    _va,
                    BreakType::Watchpoint(_kind),
                    BreakRequest::Software,
                )) = bp
                {
                    unimplemented!("Shouldn't have ever set a software watchpoint!")
                } else if dr6.contains(debugregs::Dr6::BS) {
                    // When the BS flag is set, any of the other debug status bits also may be set.
                    dr6.remove(debugregs::Dr6::BS);
                    Some(ThreadStopReason::DoneStep)
                } else {
                    None
                };
                // Sanity check that we indeed handled all bits in dr6 (except RTM
                // which isn't a condition):
                if !dr6.difference(debugregs::Dr6::RTM).is_empty() {
                    // The code assumes that only one BP (or BS) condition gets set
                    // for a single IRQ. If multiple conditions can trigger per IRQ,
                    // we need to rethink this code.
                    //
                    // Maybe we have to handle every potential flag in dr6 in some
                    // loop one after the other, or ignore some? For now, we just
                    // log and then clear/ignore the unhandled bits:
                    error!("Unhandled/ignored these conditions in dr6: {:?}", dr6);
                    dr6 = debugregs::Dr6::empty(); // This will clear RTM (we don't use this atm.)
                }
                unsafe { debugregs::dr6_write(dr6) };
                stop
            }
        }
    }
fn determine_stop_reason ( & mut self , reason : KCoreStopReason ) -> Option < ThreadStopReason < u64 > > { match reason { KCoreStopReason :: ConnectionInterrupt => Some ( ThreadStopReason :: Signal ( Signal :: SIGTRAP ) ) , KCoreStopReason :: BreakpointInterrupt => { unimplemented ! ( " " ) ; //Some(ThreadStopReason::SwBreak(NonZeroUsize::new(1).unwrap())) } KCoreStopReason :: DebugInterrupt => { // Safety: We are in the kernel so we can access dr6. let mut dr6 = unsafe { debugregs :: dr6 ( ) } ; let bp = if dr6 . contains ( debugregs :: Dr6 :: B0 ) { dr6 . remove ( debugregs :: Dr6 :: B0 ) ; self . hw_break_points [ 0 ] } else if dr6 . contains ( debugregs :: Dr6 :: B1 ) { dr6 . remove ( debugregs :: Dr6 :: B1 ) ; self . hw_break_points [ 1 ] } else if dr6 . contains ( debugregs :: Dr6 :: B2 ) { dr6 . remove ( debugregs :: Dr6 :: B2 ) ; self . hw_break_points [ 2 ] } else if dr6 . contains ( debugregs :: Dr6 :: B3 ) { dr6 . remove ( debugregs :: Dr6 :: B3 ) ; self . hw_break_points [ 3 ] } else { // If None, we are either single-stepping (debugregs::Dr6::BS, // handled below) or are at the start of the kernel (no // breakpoints were set yet) None } ; // Map things to a gdbstub stop reason: let stop : Option < ThreadStopReason < u64 > > = if let Some ( BreakState ( _va , BreakType :: Breakpoint , BreakRequest :: Hardware , ) ) = bp { Some ( ThreadStopReason :: HwBreak ( NonZeroUsize :: new ( 1 ) . unwrap ( ) ) ) } else if let Some ( BreakState ( _va , BreakType :: Breakpoint , BreakRequest :: Software ) ) = bp { Some ( ThreadStopReason :: SwBreak ( NonZeroUsize :: new ( 1 ) . unwrap ( ) ) ) } else if let Some ( BreakState ( va , BreakType :: Watchpoint ( kind ) , BreakRequest :: Hardware , ) ) = bp { Some ( ThreadStopReason :: Watch { tid : NonZeroUsize :: new ( 1 ) . unwrap ( ) , kind , addr : va . as_u64 ( ) , } ) } else if let Some ( BreakState ( _va , BreakType :: Watchpoint ( _kind ) , BreakRequest :: Software , ) ) = bp { unimplemented ! ( " " ) } else if dr6 . contains ( debugregs :: Dr6 :: BS ) { // When the BS flag is set, any of the other debug status bits also may be set. dr6 . remove ( debugregs :: Dr6 :: BS ) ; Some ( ThreadStopReason :: DoneStep ) } else { None } ; // Sanity check that we indeed handled all bits in dr6 (except RTM // which isn't a condition): if ! dr6 . difference ( debugregs :: Dr6 :: RTM ) . is_empty ( ) { // The code assumes that only one BP (or BS) condition gets set // for a single IRQ. If multiple conditions can trigger per IRQ, // we need to rethink this code. // // Maybe we have to handle every potential flag in dr6 in some // loop one after the other, or ignore some? For now, we just // log and then clear/ignore the unhandled bits: error ! ( " " dr6 ) ; dr6 = debugregs :: Dr6 :: empty ( ) ; // This will clear RTM (we don't use this atm.) } unsafe { debugregs :: dr6_write ( dr6 ) } ; stop } } }
Figures out why a core got a debug interrupt by looking through the
hardware debug register and reading which one was hit.
Figures out why a core got a debug interrupt by looking through the hardware debug register and reading which one was hit .
&mut self
reason
KCoreStopReason
&mut self
reason
KCoreStopReason