Hopefully fail to break anything in the process of syncing with trunk (r47786)
[reactos.git] / ntoskrnl / mm / powerpc / pfault.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/powerpc/pfault.c
5 * PURPOSE: Paging file functions
6 *
7 * PROGRAMMERS: David Welch (welch@mcmail.com)
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 #include <ppcmmu/mmu.h>
16
17 /* EXTERNS *******************************************************************/
18
19 NTSTATUS
20 NTAPI
21 MmNotPresentFault(KPROCESSOR_MODE Mode,
22 ULONG_PTR Address,
23 BOOLEAN FromMdl);
24 extern ULONG KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2);
25
26 /* FUNCTIONS *****************************************************************/
27
28 VOID MmpPpcTrapFrameToTrapFrame(ppc_trap_frame_t *frame, PKTRAP_FRAME Tf)
29 {
30 RtlCopyMemory(&Tf->Gpr0, frame->gpr, 12 * sizeof(ULONG));
31 Tf->Lr = frame->lr;
32 Tf->Cr = frame->cr;
33 Tf->Ctr = frame->ctr;
34 Tf->Xer = frame->xer;
35 Tf->Iar = frame->srr0;
36 Tf->Msr = frame->srr1 & 0xffff;
37 Tf->Dr0 = frame->dar;
38 Tf->Dr1 = frame->dsisr;
39 }
40
41 void CopyFrame(int *oldframe, int *ourframe)
42 {
43 int i;
44
45 for (i = 0; i < sizeof(ppc_trap_frame_t) / sizeof(int); i++)
46 {
47 ourframe[i] = GetPhys((int)&oldframe[i]);
48 }
49 }
50
51 void KiPageFaultHandler(int trap, ppc_trap_frame_t *frame)
52 {
53 NTSTATUS Status = STATUS_SUCCESS;
54 KPROCESSOR_MODE Mode;
55 EXCEPTION_RECORD Er;
56 KTRAP_FRAME Tf;
57 BOOLEAN AccessFault = !!(frame->dsisr & (1<<28));
58 vaddr_t VirtualAddr;
59 PVOID TrapInfo = NULL;
60
61 /* get the faulting address */
62 if (trap == 4) /* Instruction miss */
63 VirtualAddr = frame->srr0;
64 else /* Data miss */
65 VirtualAddr = frame->dar;
66
67 /* MSR_PR */
68 Mode = frame->srr1 & 0x4000 ? UserMode : KernelMode;
69 DPRINT("Page Fault at %08x\n", frame->srr0);
70
71 /* handle the fault */
72 if (AccessFault)
73 {
74 Status = MmAccessFault(Mode, (PVOID)VirtualAddr, FALSE, TrapInfo);
75 }
76 else
77 {
78 Status = MmNotPresentFault(Mode, VirtualAddr, FALSE);
79 }
80
81 if (NT_SUCCESS(Status))
82 {
83 MmuCallbackRet();
84 }
85
86 if (KeGetCurrentThread()->ApcState.UserApcPending)
87 {
88 KIRQL oldIrql;
89
90 KeRaiseIrql(APC_LEVEL, &oldIrql);
91 KiDeliverApc(UserMode, NULL, NULL);
92 KeLowerIrql(oldIrql);
93 }
94
95 MmpPpcTrapFrameToTrapFrame(frame, &Tf);
96
97 Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
98 Er.ExceptionFlags = 0;
99 Er.ExceptionRecord = NULL;
100 Er.ExceptionAddress = (PVOID)frame->srr0;
101 Er.NumberParameters = 2;
102 Er.ExceptionInformation[0] = AccessFault;
103 Er.ExceptionInformation[1] = VirtualAddr;
104
105 /* FIXME: Which exceptions are noncontinuable? */
106 Er.ExceptionFlags = 0;
107
108 KiDispatchException(&Er, 0, &Tf, Mode, TRUE);
109 MmuCallbackRet();
110 }
111