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?re…
==============================================================================
--- 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;