ReactOS 0.4.15-dev-7842-g558ab78
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 229 of file trapc.c.

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

Referenced by KiInitializePcr().

◆ KiDataAbortHandler()

NTSTATUS KiDataAbortHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 518 of file trapc.c.

519{
522 ASSERT(TrapFrame->Reserved == 0xBADB0D00);
523
524 DPRINT1("[ABORT] (%x) @ %p/%p/%p\n",
525 KeArmFaultStatusRegisterGet(), Address, TrapFrame->Lr, TrapFrame->Pc);
526 while (TRUE);
527
528 //
529 // Check if this is a page fault
530 //
532 {
534 Address,
535 KiGetPreviousMode(TrapFrame),
536 TrapFrame);
537 if (NT_SUCCESS(Status)) return Status;
538 }
539
540 //
541 // Unhandled
542 //
544 ASSERT(FALSE);
545 return STATUS_SUCCESS;
546}
FORCEINLINE ULONG KeArmFaultAddressRegisterGet(VOID)
Definition: intrin_i.h:70
FORCEINLINE ULONG KeArmFaultStatusRegisterGet(VOID)
Definition: intrin_i.h:44
LONG NTSTATUS
Definition: precomp.h:26
#define UNIMPLEMENTED
Definition: debug.h:115
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI MmAccessFault(IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: mmfault.c:209
static WCHAR Address[46]
Definition: ping.c:68
#define STATUS_SUCCESS
Definition: shellext.h:65
void * PVOID
Definition: typedefs.h:50

◆ 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 354 of file trapc.c.

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

◆ KiPrefetchAbortHandler()

NTSTATUS KiPrefetchAbortHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 438 of file trapc.c.

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

◆ KiSoftwareInterruptHandler()

VOID KiSoftwareInterruptHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 549 of file trapc.c.

550{
554 ASSERT(TrapFrame->Reserved == 0xBADB0D00);
555
556 DPRINT1("[SWI] @ %p/%p\n", TrapFrame->Lr, TrapFrame->Pc);
557 while (TRUE);
558
559 //
560 // Get the current thread
561 //
563
564 //
565 // Isolate previous mode
566 //
567 PreviousMode = KiGetPreviousMode(TrapFrame);
568
569 //
570 // Save old previous mode
571 //
572 TrapFrame->PreviousMode = PreviousMode;
573 TrapFrame->TrapFrame = (ULONG_PTR)Thread->TrapFrame;
574
575 //
576 // Save previous mode and trap frame
577 //
578 Thread->TrapFrame = TrapFrame;
579 Thread->PreviousMode = PreviousMode;
580
581 //
582 // Read the opcode
583 //
584 Instruction = *(PULONG)(TrapFrame->Pc - sizeof(ULONG));
585
586 //
587 // Call the service call dispatcher
588 //
590}
#define ULONG_PTR
Definition: config.h:101
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
VOID KiSystemService(IN PKTHREAD Thread, IN PKTRAP_FRAME TrapFrame, IN ULONG Instruction)
Definition: traphandler.c:234

◆ KiSwapProcess()

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

Definition at line 97 of file trapc.c.

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

◆ KiUndefinedExceptionHandler()

NTSTATUS KiUndefinedExceptionHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 593 of file trapc.c.

594{
595 ASSERT(TrapFrame->Reserved == 0xBADB0D00);
596
597 //
598 // This should never happen
599 //
600 DPRINT1("[UNDEF] @ %p/%p\n", TrapFrame->Lr, TrapFrame->Pc);
602 ASSERT(FALSE);
603 return STATUS_SUCCESS;
604}