Author: ros-arm-bringup Date: Sun Jul 13 18:34:44 2008 New Revision: 34480
URL: http://svn.reactos.org/svn/reactos?rev=34480&view=rev Log: - Start implementing KiPrefetchAbortHandler for BKPT instructions. - We pretty much try to duplicate what happens on x86, and build an exception record with the right information. - We are seeing the debug string in R1 and its length in R2, so we're on the right track. - We call KiDispatchException now, which isn't yet implemented. - Yup, all this work just to see a damn debug string the "*proper* NT way". Thanks, asshole.
Modified: trunk/reactos/ntoskrnl/ke/arm/trapc.c
Modified: trunk/reactos/ntoskrnl/ke/arm/trapc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trapc.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] Sun Jul 13 18:34:44 2008 @@ -434,8 +434,78 @@ NTSTATUS KiPrefetchAbortHandler(IN PKTRAP_FRAME TrapFrame) { + PVOID Address = (PVOID)KeArmFaultAddressRegisterGet(); ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00); + ULONG Instruction = *(PULONG)TrapFrame->Pc; + ULONG DebugType, Parameter0; + EXCEPTION_RECORD ExceptionRecord; + + // + // What we *SHOULD* do is look at the instruction fault status register + // and see if it's equal to 2 (debug trap). Unfortunately QEMU doesn't seem + // to emulate this behaviour properly, so we use a workaround. + // + //if (KeArmInstructionFaultStatusRegisterGet() == 2) + if (Instruction & 0xE1200070) // BKPT + { + // + // Okay, we know this is a breakpoint, extract the index + // + DebugType = Instruction & 0xF; + if (DebugType == BREAKPOINT_PRINT) + { + // + // Debug Service + // + Parameter0 = TrapFrame->R0; + } + else + { + // + // Standard INT3 (emulate x86 behavior) + // + Parameter0 = STATUS_SUCCESS; + } + + // + // Build the exception record + // + ExceptionRecord.ExceptionCode = STATUS_BREAKPOINT; + ExceptionRecord.ExceptionFlags = 0; + ExceptionRecord.ExceptionRecord = NULL; + ExceptionRecord.ExceptionAddress = (PVOID)TrapFrame->Pc; + ExceptionRecord.NumberParameters = 3; + + // + // Build the parameters + // + ExceptionRecord.ExceptionInformation[0] = Parameter0; + ExceptionRecord.ExceptionInformation[1] = TrapFrame->R1; + ExceptionRecord.ExceptionInformation[2] = TrapFrame->R2; + + // + // Dispatch the exception + // + KiDispatchException(&ExceptionRecord, + NULL, + TrapFrame, + KiGetPreviousMode(TrapFrame), + TRUE); + + // + // TODO + // + while (TRUE); + } + + // + // Unhandled + // while (TRUE); + DPRINT1("[PREFETCH ABORT] (%x) @ %p/%p/%p\n", + KeArmInstructionFaultStatusRegisterGet(), Address, TrapFrame->SvcLr, TrapFrame->Pc); + UNIMPLEMENTED; + ASSERT(FALSE); return STATUS_SUCCESS; }
@@ -453,11 +523,14 @@ { Status = MmAccessFault(FALSE, Address, - KernelMode, + KiGetPreviousMode(TrapFrame), TrapFrame); if (Status == STATUS_SUCCESS) return Status; }
+ // + // Unhandled + // DPRINT1("[ABORT] (%x) @ %p/%p/%p\n", KeArmFaultStatusRegisterGet(), Address, TrapFrame->SvcLr, TrapFrame->Pc); UNIMPLEMENTED;