ReactOS  0.4.14-dev-342-gdc047f9
trapc.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for trapc.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI KiSwapProcess (IN PKPROCESS NewProcess, IN PKPROCESS OldProcess)
 
VOID KiApcInterrupt (VOID)
 
VOID KiInterruptHandler (IN PKTRAP_FRAME TrapFrame, IN ULONG Reserved)
 
NTSTATUS KiPrefetchAbortHandler (IN PKTRAP_FRAME TrapFrame)
 
NTSTATUS KiDataAbortHandler (IN PKTRAP_FRAME TrapFrame)
 
VOID KiSoftwareInterruptHandler (IN PKTRAP_FRAME TrapFrame)
 
NTSTATUS KiUndefinedExceptionHandler (IN PKTRAP_FRAME TrapFrame)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file trapc.c.

Function Documentation

◆ KiApcInterrupt()

VOID KiApcInterrupt ( VOID  )

Definition at line 228 of file trapc.c.

229 {
231  KEXCEPTION_FRAME ExceptionFrame;
232  PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
233 
234  DPRINT1("[APC TRAP]\n");
235  while (TRUE);
236 
237  //
238  // Isolate previous mode
239  //
240  PreviousMode = KiGetPreviousMode(TrapFrame);
241 
242  //
243  // FIXME-USER: Handle APC interrupt while in user-mode
244  //
246 
247  //
248  // Disable interrupts
249  //
250  _disable();
251 
252  //
253  // Clear APC interrupt
254  //
256 
257  //
258  // Re-enable interrupts
259  //
260  _enable();
261 
262  //
263  // Deliver APCs
264  //
265  KiDeliverApc(PreviousMode, &ExceptionFrame, TrapFrame);
266 }
#define TRUE
Definition: types.h:120
void __cdecl _enable(void)
Definition: intrin_arm.h:373
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define KiGetPreviousMode(tf)
Definition: ke.h:180
#define DPRINT1
Definition: precomp.h:8
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:282
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define KeGetCurrentThread
Definition: hal.h:44
VOID NTAPI KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: apc.c:302
#define APC_LEVEL
Definition: env_spec_w32.h:695

Referenced by KiInitializePcr().

◆ KiDataAbortHandler()

NTSTATUS KiDataAbortHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 517 of file trapc.c.

518 {
521  ASSERT(TrapFrame->Reserved == 0xBADB0D00);
522 
523  DPRINT1("[ABORT] (%x) @ %p/%p/%p\n",
524  KeArmFaultStatusRegisterGet(), Address, TrapFrame->Lr, TrapFrame->Pc);
525  while (TRUE);
526 
527  //
528  // Check if this is a page fault
529  //
531  {
533  Address,
534  KiGetPreviousMode(TrapFrame),
535  TrapFrame);
536  if (NT_SUCCESS(Status)) return Status;
537  }
538 
539  //
540  // Unhandled
541  //
543  ASSERT(FALSE);
544  return STATUS_SUCCESS;
545 }
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI MmAccessFault(IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: mmfault.c:204
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE ULONG KeArmFaultStatusRegisterGet(VOID)
Definition: intrin_i.h:44
static WCHAR Address[46]
Definition: ping.c:68
FORCEINLINE ULONG KeArmFaultAddressRegisterGet(VOID)
Definition: intrin_i.h:70
void * PVOID
Definition: retypes.h:9
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
#define KiGetPreviousMode(tf)
Definition: ke.h:180
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:114
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ KiInterruptHandler()

VOID KiInterruptHandler ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Reserved 
)

FIXME: use a global table in ntoskrnl instead of HAL?

FIXME: this should probably go into a table in ntoskrnl

Definition at line 353 of file trapc.c.

355 {
356  KIRQL OldIrql, Irql;
357  ULONG InterruptCause;//, InterruptMask;
358  PKIPCR Pcr;
359  PKTRAP_FRAME OldTrapFrame;
360  ASSERT(TrapFrame->Reserved == 0xBADB0D00);
361 
362  //
363  // Increment interrupt count
364  //
365  Pcr = (PKIPCR)KeGetPcr();
366  Pcr->Prcb.InterruptCount++;
367 
368  //
369  // Get the old IRQL
370  //
372  TrapFrame->PreviousIrql = OldIrql;
373 
374  //
375  // Get the interrupt source
376  //
377  InterruptCause = HalGetInterruptSource();
378  //DPRINT1("[INT] (%x) @ %p %p\n", InterruptCause, TrapFrame->SvcLr, TrapFrame->Pc);
379 
380  //
381  // Get the new IRQL and Interrupt Mask
382  //
384  //Irql = Pcr->IrqlMask[InterruptCause];
385  //InterruptMask = Pcr->IrqlTable[Irql];
386  Irql = 0;
387  __debugbreak();
388 
389  //
390  // Raise to the new IRQL
391  //
392  KfRaiseIrql(Irql);
393 
394  //
395  // The clock ISR wants the trap frame as a parameter
396  //
397  OldTrapFrame = KeGetCurrentThread()->TrapFrame;
398  KeGetCurrentThread()->TrapFrame = TrapFrame;
399 
400  //
401  // Check if this interrupt is at DISPATCH or higher
402  //
403  if (Irql > DISPATCH_LEVEL)
404  {
405  //
406  // FIXME-TODO: Switch to interrupt stack
407  //
408  //DPRINT1("[ISR]\n");
409  }
410  else
411  {
412  //
413  // We know this is APC or DPC.
414  //
415  //DPRINT1("[DPC/APC]\n");
417  }
418 
419  //
420  // Call the registered interrupt routine
421  //
423  //Pcr->InterruptRoutine[Irql]();
424  __debugbreak();
425  ASSERT(KeGetCurrentThread()->TrapFrame == TrapFrame);
426  KeGetCurrentThread()->TrapFrame = OldTrapFrame;
427 // DPRINT1("[ISR RETURN]\n");
428 
429  //
430  // Restore IRQL and interrupts
431  //
433  _enable();
434 }
ULONG HalGetInterruptSource(VOID)
Definition: pic.c:108
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
void __cdecl _enable(void)
Definition: intrin_arm.h:373
struct _KIPCR * PKIPCR
_Out_ PKIRQL Irql
Definition: csq.h:179
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
#define KeGetPcr()
Definition: ke.h:25
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG InterruptCount
Definition: ketypes.h:732
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
KPRCB Prcb
Definition: ketypes.h:889
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:282
unsigned int ULONG
Definition: retypes.h:1
#define KeGetCurrentThread
Definition: hal.h:44

◆ KiPrefetchAbortHandler()

NTSTATUS KiPrefetchAbortHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 437 of file trapc.c.

438 {
440  ASSERT(TrapFrame->Reserved == 0xBADB0D00);
441  ULONG Instruction = *(PULONG)TrapFrame->Pc;
442  ULONG DebugType, Parameter0;
443  EXCEPTION_RECORD ExceptionRecord;
444 
445  DPRINT1("[PREFETCH ABORT] (%x) @ %p/%p/%p\n",
446  KeArmInstructionFaultStatusRegisterGet(), Address, TrapFrame->Lr, TrapFrame->Pc);
447  while (TRUE);
448 
449  //
450  // What we *SHOULD* do is look at the instruction fault status register
451  // and see if it's equal to 2 (debug trap). Unfortunately QEMU doesn't seem
452  // to emulate this behaviour properly, so we use a workaround.
453  //
454  //if (KeArmInstructionFaultStatusRegisterGet() == 2)
455  if (Instruction & 0xE1200070) // BKPT
456  {
457  //
458  // Okay, we know this is a breakpoint, extract the index
459  //
460  DebugType = Instruction & 0xF;
461  if (DebugType == BREAKPOINT_PRINT)
462  {
463  //
464  // Debug Service
465  //
466  Parameter0 = TrapFrame->R0;
467  TrapFrame->Pc += sizeof(ULONG);
468  }
469  else
470  {
471  //
472  // Standard INT3 (emulate x86 behavior)
473  //
474  Parameter0 = STATUS_SUCCESS;
475  }
476 
477  //
478  // Build the exception record
479  //
480  ExceptionRecord.ExceptionCode = STATUS_BREAKPOINT;
481  ExceptionRecord.ExceptionFlags = 0;
482  ExceptionRecord.ExceptionRecord = NULL;
483  ExceptionRecord.ExceptionAddress = (PVOID)TrapFrame->Pc;
484  ExceptionRecord.NumberParameters = 3;
485 
486  //
487  // Build the parameters
488  //
489  ExceptionRecord.ExceptionInformation[0] = Parameter0;
490  ExceptionRecord.ExceptionInformation[1] = TrapFrame->R1;
491  ExceptionRecord.ExceptionInformation[2] = TrapFrame->R2;
492 
493  //
494  // Dispatch the exception
495  //
496  KiDispatchException(&ExceptionRecord,
497  NULL,
498  TrapFrame,
499  KiGetPreviousMode(TrapFrame),
500  TRUE);
501 
502  //
503  // We're done
504  //
505  return STATUS_SUCCESS;
506  }
507 
508  //
509  // Unhandled
510  //
512  ASSERT(FALSE);
513  return STATUS_SUCCESS;
514 }
#define TRUE
Definition: types.h:120
VOID NTAPI KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, PKEXCEPTION_FRAME ExceptionFrame, PKTRAP_FRAME Tf, KPROCESSOR_MODE PreviousMode, BOOLEAN SearchFrames)
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
FORCEINLINE ULONG KeArmFaultAddressRegisterGet(VOID)
Definition: intrin_i.h:70
void * PVOID
Definition: retypes.h:9
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define BREAKPOINT_PRINT
Definition: kdtypes.h:51
FORCEINLINE ULONG KeArmInstructionFaultStatusRegisterGet(VOID)
Definition: intrin_i.h:57
unsigned int * PULONG
Definition: retypes.h:1
#define KiGetPreviousMode(tf)
Definition: ke.h:180
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ KiSoftwareInterruptHandler()

VOID KiSoftwareInterruptHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 548 of file trapc.c.

549 {
552  ULONG Instruction;
553  ASSERT(TrapFrame->Reserved == 0xBADB0D00);
554 
555  DPRINT1("[SWI] @ %p/%p\n", TrapFrame->Lr, TrapFrame->Pc);
556  while (TRUE);
557 
558  //
559  // Get the current thread
560  //
562 
563  //
564  // Isolate previous mode
565  //
566  PreviousMode = KiGetPreviousMode(TrapFrame);
567 
568  //
569  // Save old previous mode
570  //
571  TrapFrame->PreviousMode = PreviousMode;
572  TrapFrame->TrapFrame = (ULONG_PTR)Thread->TrapFrame;
573 
574  //
575  // Save previous mode and trap frame
576  //
577  Thread->TrapFrame = TrapFrame;
578  Thread->PreviousMode = PreviousMode;
579 
580  //
581  // Read the opcode
582  //
583  Instruction = *(PULONG)(TrapFrame->Pc - sizeof(ULONG));
584 
585  //
586  // Call the service call dispatcher
587  //
588  KiSystemService(Thread, TrapFrame, Instruction);
589 }
#define TRUE
Definition: types.h:120
VOID KiSystemService(IN PKTHREAD Thread, IN PKTRAP_FRAME TrapFrame, IN ULONG Instruction)
Definition: stubs.c:399
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned int * PULONG
Definition: retypes.h:1
#define KiGetPreviousMode(tf)
Definition: ke.h:180
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define KeGetCurrentThread
Definition: hal.h:44

◆ KiSwapProcess()

VOID NTAPI KiSwapProcess ( IN PKPROCESS  NewProcess,
IN PKPROCESS  OldProcess 
)

Definition at line 96 of file trapc.c.

98 {
99  ARM_TTB_REGISTER TtbRegister;
100  DPRINT1("Swapping from: %p (%16s) to %p (%16s)\n",
101  OldProcess, ((PEPROCESS)OldProcess)->ImageFileName,
102  NewProcess, ((PEPROCESS)NewProcess)->ImageFileName);
103 
104  //
105  // Update the page directory base
106  //
107  TtbRegister.AsUlong = NewProcess->DirectoryTableBase[0];
108  ASSERT(TtbRegister.Reserved == 0);
110 
111  //
112  // FIXME: Flush the TLB
113  //
114 
115 
116  DPRINT1("Survived!\n");
117  while (TRUE);
118 }
#define TRUE
Definition: types.h:120
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE VOID KeArmTranslationTableRegisterSet(IN ARM_TTB_REGISTER Ttb)
Definition: intrin_i.h:145

◆ KiUndefinedExceptionHandler()

NTSTATUS KiUndefinedExceptionHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 592 of file trapc.c.

593 {
594  ASSERT(TrapFrame->Reserved == 0xBADB0D00);
595 
596  //
597  // This should never happen
598  //
599  DPRINT1("[UNDEF] @ %p/%p\n", TrapFrame->Lr, TrapFrame->Pc);
601  ASSERT(FALSE);
602  return STATUS_SUCCESS;
603 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:114
return STATUS_SUCCESS
Definition: btrfs.c:2938