NT4/private/ntos/fw/alpha/fwkd.c
2020-09-30 17:12:29 +02:00

700 lines
20 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifdef ALPHA_FW_KDHOOKS
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
fwkd.c
Abstract:
This module implements the code to interface the firware exception
path with the kernel debugger stub.
Author:
Joe Notarangelo 31-Mar-93
Environment:
Firmware.
Revision History:
--*/
#include "fwp.h"
#include "fwpexcpt.h"
#include "ntosdef.h"
VOID
FwFrameToKdFrames(
PFW_EXCEPTION_FRAME FirmwareFrame,
PKTRAP_FRAME TrapFrame,
PCONTEXT Context
);
VOID
FwFrameFromKdFrames(
PFW_EXCEPTION_FRAME FirmwareFrame,
PKTRAP_FRAME TrapFrame,
PCONTEXT Context
);
VOID
KeContextFromKframes (
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN OUT PCONTEXT ContextFrame
);
VOID
KeContextToKframes (
IN OUT PKTRAP_FRAME TrapFrame,
IN OUT PKEXCEPTION_FRAME ExceptionFrame,
IN PCONTEXT ContextFrame,
IN ULONG ContextFlags,
IN KPROCESSOR_MODE PreviousMode
);
BOOLEAN
FwKdProcessBreakpoint(
PFW_EXCEPTION_FRAME FirmwareExceptionFrame
)
/*++
Routine Description:
This function implements the glue logic between the firmware
exception path and the kernel debugger stub. It must translate
the firmware exception frame to a kernel trap and context frame.
Arguments:
FirmwareExceptionFrame - supplies a pointer to the firmware exception
frame.
Return Value:
The value TRUE is returned if the breakpoint is processed by the
kernel debugger stub, FALSE is returned otherwise.
--*/
{
KTRAP_FRAME TrapFrame;
CONTEXT Context;
PEXCEPTION_RECORD ExceptionRecord;
//
// Translate the firmware exception frame to the frames expected
// by the kernel debugger stub.
//
FwFrameToKdFrames( FirmwareExceptionFrame, &TrapFrame, &Context );
ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame.ExceptionRecord;
//
// Determine if this is a kernel debugger breakpoint, if it is not
// return FALSE to indicate that the breakpoint was not handled.
//
if( !KdIsThisAKdTrap(ExceptionRecord,
&Context,
KernelMode) ) {
return FALSE;
}
//
// Call the kernel debugger to handle the breakpoint.
//
(VOID)KdpTrap( &TrapFrame,
ExceptionRecord,
&Context,
KernelMode,
FALSE );
//
// Transfer the kernel frames back into the firmware frame.
//
FwFrameFromKdFrames( FirmwareExceptionFrame, &TrapFrame, &Context );
return TRUE;
}
VOID
FwFrameToKdFrames(
PFW_EXCEPTION_FRAME FirmwareFrame,
PKTRAP_FRAME TrapFrame,
PCONTEXT Context
)
/*++
Routine Description:
Convert the firmware exception frame to the kernel frames format.
Arguments:
FirmwareFrame - supplies a pointer to the firmware exception frame.
TrapFrame - supplies a pointer to the kernel trap frame.
Context - supplies a pointer to the kernel context
Return Value:
None.
--*/
{
PEXCEPTION_RECORD ExceptionRecord;
KEXCEPTION_FRAME ExceptionFrame;
//
// Build the kernel trap frame.
//
//
// Volatile floating registers.
//
TrapFrame->FltF0 = FirmwareFrame->ExceptionF0;
TrapFrame->Fpcr = 0; //not saved by firmware
TrapFrame->FltF1 = FirmwareFrame->ExceptionF1;
TrapFrame->FltF10 = FirmwareFrame->ExceptionF10;
TrapFrame->FltF11 = FirmwareFrame->ExceptionF11;
TrapFrame->FltF12 = FirmwareFrame->ExceptionF12;
TrapFrame->FltF13 = FirmwareFrame->ExceptionF13;
TrapFrame->FltF14 = FirmwareFrame->ExceptionF14;
TrapFrame->FltF15 = FirmwareFrame->ExceptionF15;
TrapFrame->FltF16 = FirmwareFrame->ExceptionF16;
TrapFrame->FltF17 = FirmwareFrame->ExceptionF17;
TrapFrame->FltF18 = FirmwareFrame->ExceptionF18;
TrapFrame->FltF19 = FirmwareFrame->ExceptionF19;
TrapFrame->FltF20 = FirmwareFrame->ExceptionF20;
TrapFrame->FltF21 = FirmwareFrame->ExceptionF21;
TrapFrame->FltF22 = FirmwareFrame->ExceptionF22;
TrapFrame->FltF23 = FirmwareFrame->ExceptionF23;
TrapFrame->FltF24 = FirmwareFrame->ExceptionF24;
TrapFrame->FltF25 = FirmwareFrame->ExceptionF25;
TrapFrame->FltF26 = FirmwareFrame->ExceptionF26;
TrapFrame->FltF27 = FirmwareFrame->ExceptionF27;
TrapFrame->FltF28 = FirmwareFrame->ExceptionF28;
TrapFrame->FltF29 = FirmwareFrame->ExceptionF29;
TrapFrame->FltF30 = FirmwareFrame->ExceptionF30;
//
// Volatile integer registers.
//
TrapFrame->IntV0 = FirmwareFrame->ExceptionV0;
TrapFrame->IntT0 = FirmwareFrame->ExceptionT0;
TrapFrame->IntT1 = FirmwareFrame->ExceptionT1;
TrapFrame->IntT2 = FirmwareFrame->ExceptionT2;
TrapFrame->IntT3 = FirmwareFrame->ExceptionT3;
TrapFrame->IntT4 = FirmwareFrame->ExceptionT4;
TrapFrame->IntT5 = FirmwareFrame->ExceptionT5;
TrapFrame->IntT6 = FirmwareFrame->ExceptionT6;
TrapFrame->IntT7 = FirmwareFrame->ExceptionT7;
TrapFrame->IntFp = FirmwareFrame->ExceptionFp;
TrapFrame->IntA0 = FirmwareFrame->ExceptionA0;
TrapFrame->IntA1 = FirmwareFrame->ExceptionA1;
TrapFrame->IntA2 = FirmwareFrame->ExceptionA2;
TrapFrame->IntA3 = FirmwareFrame->ExceptionA3;
TrapFrame->IntA4 = FirmwareFrame->ExceptionA4;
TrapFrame->IntA5 = FirmwareFrame->ExceptionA5;
TrapFrame->IntT8 = FirmwareFrame->ExceptionT8;
TrapFrame->IntT9 = FirmwareFrame->ExceptionT9;
TrapFrame->IntT10 = FirmwareFrame->ExceptionT10;
TrapFrame->IntT11 = FirmwareFrame->ExceptionT11;
TrapFrame->IntRa = FirmwareFrame->ExceptionRa;
TrapFrame->IntT12 = FirmwareFrame->ExceptionT12;
TrapFrame->IntAt = FirmwareFrame->ExceptionAt;
TrapFrame->IntGp = FirmwareFrame->ExceptionGp;
TrapFrame->IntSp = FirmwareFrame->ExceptionSp;
//
// Exception Record.
//
ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
ExceptionRecord->ExceptionCode = STATUS_BREAKPOINT;
ExceptionRecord->ExceptionAddress = (PVOID)(LONG)
FirmwareFrame->ExceptionFaultingInstructionAddress;
ExceptionRecord->ExceptionInformation[0] =
FirmwareFrame->ExceptionParameter1;
ExceptionRecord->ExceptionFlags = 0;
ExceptionRecord->ExceptionAddress = NULL;
ExceptionRecord->NumberParameters = 0;
//
// Control data.
//
TrapFrame->Fir = FirmwareFrame->ExceptionFaultingInstructionAddress;
TrapFrame->Psr = 0;
TrapFrame->OldIrql = 0;
TrapFrame->PreviousMode = 0;
//
// Build the Context Frame, using the standard kernel routines to
// transfer kernel frames to a context frame. This strategy requires
// building a local exception frame to pass in to the common routine.
//
ExceptionFrame.IntS0 = FirmwareFrame->ExceptionS0;
ExceptionFrame.IntS1 = FirmwareFrame->ExceptionS1;
ExceptionFrame.IntS2 = FirmwareFrame->ExceptionS2;
ExceptionFrame.IntS3 = FirmwareFrame->ExceptionS3;
ExceptionFrame.IntS4 = FirmwareFrame->ExceptionS4;
ExceptionFrame.IntS5 = FirmwareFrame->ExceptionS5;
ExceptionFrame.FltF2 = FirmwareFrame->ExceptionF2;
ExceptionFrame.FltF3 = FirmwareFrame->ExceptionF3;
ExceptionFrame.FltF4 = FirmwareFrame->ExceptionF4;
ExceptionFrame.FltF5 = FirmwareFrame->ExceptionF5;
ExceptionFrame.FltF6 = FirmwareFrame->ExceptionF6;
ExceptionFrame.FltF7 = FirmwareFrame->ExceptionF7;
ExceptionFrame.FltF8 = FirmwareFrame->ExceptionF8;
ExceptionFrame.FltF9 = FirmwareFrame->ExceptionF9;
Context->ContextFlags = CONTEXT_FULL;
KeContextFromKframes( TrapFrame, &ExceptionFrame, Context );
}
VOID
FwFrameFromKdFrames(
PFW_EXCEPTION_FRAME FirmwareFrame,
PKTRAP_FRAME TrapFrame,
PCONTEXT Context
)
/*++
Routine Description:
Convert the firmware exception frame to the kernel frames format.
Arguments:
FirmwareFrame - supplies a pointer to the firmware exception frame.
TrapFrame - supplies a pointer to the kernel trap frame.
Context - supplies a pointer to the kernel context
Return Value:
None.
--*/
{
KEXCEPTION_FRAME ExceptionFrame;
//
// Build the kernel frames (trap and exception) from the
// context frame using the standard kernel routines.
//
KeContextToKframes( TrapFrame,
&ExceptionFrame,
Context,
CONTEXT_FULL,
KernelMode );
//
// Extract the non-volatile register state from the ExceptionFrame
// and re-populate the firmware frame.
//
FirmwareFrame->ExceptionS0 = ExceptionFrame.IntS0;
FirmwareFrame->ExceptionS1 = ExceptionFrame.IntS1;
FirmwareFrame->ExceptionS2 = ExceptionFrame.IntS2;
FirmwareFrame->ExceptionS3 = ExceptionFrame.IntS3;
FirmwareFrame->ExceptionS4 = ExceptionFrame.IntS4;
FirmwareFrame->ExceptionS5 = ExceptionFrame.IntS5;
FirmwareFrame->ExceptionF2 = ExceptionFrame.FltF2;
FirmwareFrame->ExceptionF3 = ExceptionFrame.FltF3;
FirmwareFrame->ExceptionF4 = ExceptionFrame.FltF4;
FirmwareFrame->ExceptionF5 = ExceptionFrame.FltF5;
FirmwareFrame->ExceptionF6 = ExceptionFrame.FltF6;
FirmwareFrame->ExceptionF7 = ExceptionFrame.FltF7;
FirmwareFrame->ExceptionF8 = ExceptionFrame.FltF8;
FirmwareFrame->ExceptionF9 = ExceptionFrame.FltF9;
//
// Extract the volatile register state from the TrapFrame and
// re-populate the firmware frame.
//
//
// Volatile floating registers.
//
FirmwareFrame->ExceptionF0 = TrapFrame->FltF0;
FirmwareFrame->ExceptionF1 = TrapFrame->FltF1;
FirmwareFrame->ExceptionF10 = TrapFrame->FltF10;
FirmwareFrame->ExceptionF11 = TrapFrame->FltF11;
FirmwareFrame->ExceptionF12 = TrapFrame->FltF12;
FirmwareFrame->ExceptionF13 = TrapFrame->FltF13;
FirmwareFrame->ExceptionF14 = TrapFrame->FltF14;
FirmwareFrame->ExceptionF15 = TrapFrame->FltF15;
FirmwareFrame->ExceptionF16 = TrapFrame->FltF16;
FirmwareFrame->ExceptionF17 = TrapFrame->FltF17;
FirmwareFrame->ExceptionF18 = TrapFrame->FltF18;
FirmwareFrame->ExceptionF19 = TrapFrame->FltF19;
FirmwareFrame->ExceptionF20 = TrapFrame->FltF20;
FirmwareFrame->ExceptionF21 = TrapFrame->FltF21;
FirmwareFrame->ExceptionF22 = TrapFrame->FltF22;
FirmwareFrame->ExceptionF23 = TrapFrame->FltF23;
FirmwareFrame->ExceptionF24 = TrapFrame->FltF24;
FirmwareFrame->ExceptionF25 = TrapFrame->FltF25;
FirmwareFrame->ExceptionF26 = TrapFrame->FltF26;
FirmwareFrame->ExceptionF27 = TrapFrame->FltF27;
FirmwareFrame->ExceptionF28 = TrapFrame->FltF28;
FirmwareFrame->ExceptionF29 = TrapFrame->FltF29;
FirmwareFrame->ExceptionF30 = TrapFrame->FltF30;
//
// Volatile integer registers.
//
FirmwareFrame->ExceptionV0 = TrapFrame->IntV0;
FirmwareFrame->ExceptionT0 = TrapFrame->IntT0;
FirmwareFrame->ExceptionT1 = TrapFrame->IntT1;
FirmwareFrame->ExceptionT2 = TrapFrame->IntT2;
FirmwareFrame->ExceptionT3 = TrapFrame->IntT3;
FirmwareFrame->ExceptionT4 = TrapFrame->IntT4;
FirmwareFrame->ExceptionT5 = TrapFrame->IntT5;
FirmwareFrame->ExceptionT6 = TrapFrame->IntT6;
FirmwareFrame->ExceptionT7 = TrapFrame->IntT7;
FirmwareFrame->ExceptionFp = TrapFrame->IntFp;
FirmwareFrame->ExceptionA0 = TrapFrame->IntA0;
FirmwareFrame->ExceptionA1 = TrapFrame->IntA1;
FirmwareFrame->ExceptionA2 = TrapFrame->IntA2;
FirmwareFrame->ExceptionA3 = TrapFrame->IntA3;
FirmwareFrame->ExceptionA4 = TrapFrame->IntA4;
FirmwareFrame->ExceptionA5 = TrapFrame->IntA5;
FirmwareFrame->ExceptionT8 = TrapFrame->IntT8;
FirmwareFrame->ExceptionT9 = TrapFrame->IntT9;
FirmwareFrame->ExceptionT10 = TrapFrame->IntT10;
FirmwareFrame->ExceptionT11 = TrapFrame->IntT11;
FirmwareFrame->ExceptionRa = TrapFrame->IntRa;
FirmwareFrame->ExceptionT12 = TrapFrame->IntT12;
FirmwareFrame->ExceptionAt = TrapFrame->IntAt;
FirmwareFrame->ExceptionGp = TrapFrame->IntGp;
FirmwareFrame->ExceptionSp = TrapFrame->IntSp;
//
// Control data.
//
FirmwareFrame->ExceptionFaultingInstructionAddress = TrapFrame->Fir;
return;
}
VOID
KeContextFromKframes (
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN OUT PCONTEXT ContextFrame
)
/*++
Routine Description:
This routine moves the selected contents of the specified trap and exception
frames into the specified context frame according to the specified context
flags.
Arguments:
TrapFrame - Supplies a pointer to a trap frame from which volatile context
should be copied into the context record.
ExceptionFrame - Supplies a pointer to an exception frame from which
context should be copied into the context record.
ContextFrame - Supplies a pointer to the context frame that receives the
context copied from the trap and exception frames.
Return Value:
None.
Implementation Notes:
The mix of structure element assignments and memory copies in the code
below is completely dependent on the layout of the context structure.
Since this code is not executed often, it is optimized for minimum size
(memory copies), rather than maximum speed (individual assignments).
--*/
{
//
// Set control information if specified.
//
if ((ContextFrame->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
//
// Set integer register gp, ra, sp, FIR, and PSR from trap frame.
//
ContextFrame->IntGp = TrapFrame->IntGp;
ContextFrame->IntSp = TrapFrame->IntSp;
ContextFrame->IntRa = TrapFrame->IntRa;
ContextFrame->Fir = TrapFrame->Fir;
ContextFrame->Psr = TrapFrame->Psr;
}
//
// Set integer register contents if specified.
//
if ((ContextFrame->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
//
// Set volatile integer registers v0 and t0 - t7 from trap frame.
//
RtlMoveMemory(&ContextFrame->IntV0, &TrapFrame->IntV0,
sizeof(ULONGLONG) * 9);
//
// Set nonvolatile integer registers s0 - s5 from exception frame.
//
RtlMoveMemory(&ContextFrame->IntS0, &ExceptionFrame->IntS0,
sizeof(ULONGLONG) * 6);
//
// Set volatile integer registers a0 - a3, a4 - a5, and t8 - t11
// from trap frame.
//
RtlMoveMemory(&ContextFrame->IntA0, &TrapFrame->IntA0,
sizeof(ULONGLONG) * 4);
ContextFrame->IntA4 = TrapFrame->IntA4;
ContextFrame->IntA5 = TrapFrame->IntA5;
RtlMoveMemory(&ContextFrame->IntT8, &TrapFrame->IntT8,
sizeof(ULONGLONG) * 4);
//
// Set volatile integer registers fp, t12 and at from trap frame.
// Set integer register zero.
//
ContextFrame->IntFp = TrapFrame->IntFp;
ContextFrame->IntT12 = TrapFrame->IntT12;
ContextFrame->IntAt = TrapFrame->IntAt;
ContextFrame->IntZero = 0;
}
//
// Set floating register contents if specified.
//
if ((ContextFrame->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) {
//
// Set volatile floating registers f0 - f1 from trap frame.
// Set volatile floating registers f10 - f30 from trap frame.
// Set floating zero register f31 to 0.
//
ContextFrame->FltF0 = TrapFrame->FltF0;
ContextFrame->FltF1 = TrapFrame->FltF1;
RtlMoveMemory(&ContextFrame->FltF10, &TrapFrame->FltF10,
sizeof(ULONGLONG) * 21);
ContextFrame->FltF31 = 0;
//
// Set nonvolatile floating registers f2 - f9 from exception frame.
//
RtlMoveMemory(&ContextFrame->FltF2, &ExceptionFrame->FltF2,
sizeof(ULONGLONG) * 8);
//
// Set floating point control register from trap frame.
//
ContextFrame->Fpcr = TrapFrame->Fpcr;
}
return;
}
VOID
KeContextToKframes (
IN OUT PKTRAP_FRAME TrapFrame,
IN OUT PKEXCEPTION_FRAME ExceptionFrame,
IN PCONTEXT ContextFrame,
IN ULONG ContextFlags,
IN KPROCESSOR_MODE PreviousMode
)
/*++
Routine Description:
This routine moves the selected contents of the specified context frame
into the specified trap and exception frames according to the specified
context flags.
Arguments:
TrapFrame - Supplies a pointer to a trap frame that receives the volatile
context from the context record.
ExceptionFrame - Supplies a pointer to an exception frame that receives
the nonvolatile context from the context record.
ContextFrame - Supplies a pointer to a context frame that contains the
context that is to be copied into the trap and exception frames.
ContextFlags - Supplies the set of flags that specify which parts of the
context frame are to be copied into the trap and exception frames.
PreviousMode - Supplies the processor mode for which the trap and exception
frames are being built.
Return Value:
None.
Implementation Notes:
The mix of structure element assignments and memory copies in the code
below is completely dependent on the layout of the context structure.
Since this code is not executed often, it is optimized for minimum size
(memory copies), rather than maximum speed (individual assignments).
--*/
{
//
// Set control information if specified.
//
if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
//
// Set integer register gp, sp, ra, FIR, and PSR in trap frame.
//
TrapFrame->IntGp = ContextFrame->IntGp;
TrapFrame->IntSp = ContextFrame->IntSp;
TrapFrame->IntRa = ContextFrame->IntRa;
TrapFrame->Fir = ContextFrame->Fir;
TrapFrame->Psr = SANITIZE_PSR(ContextFrame->Psr, PreviousMode);
}
//
// Set integer register contents if specified.
//
if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
//
// Set volatile integer registers v0 and t0 - t7 in trap frame.
//
RtlMoveMemory(&TrapFrame->IntV0, &ContextFrame->IntV0,
sizeof(ULONGLONG) * 9);
//
// Set nonvolatile integer registers s0 - s5 in exception frame.
//
RtlMoveMemory(&ExceptionFrame->IntS0, &ContextFrame->IntS0,
sizeof(ULONGLONG) * 6);
//
// Set volatile integer registers a0 - a3, a4 - a5, and t8 - t11
// in trap frame.
//
RtlMoveMemory(&TrapFrame->IntA0, &ContextFrame->IntA0,
sizeof(ULONGLONG) * 4);
TrapFrame->IntA4 = ContextFrame->IntA4;
TrapFrame->IntA5 = ContextFrame->IntA5;
RtlMoveMemory(&TrapFrame->IntT8, &ContextFrame->IntT8,
sizeof(ULONGLONG) * 4);
//
// Set volatile integer registers fp, t12 and at in trap frame.
//
TrapFrame->IntFp = ContextFrame->IntFp;
TrapFrame->IntT12 = ContextFrame->IntT12;
TrapFrame->IntAt = ContextFrame->IntAt;
}
//
// Set floating register contents if specified.
//
if ((ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) {
//
// Set volatile floating registers f0 - f1 in trap frame.
// Set volatile floating registers f10 - f30 in trap frame.
//
TrapFrame->FltF0 = ContextFrame->FltF0;
TrapFrame->FltF1 = ContextFrame->FltF1;
RtlMoveMemory(&TrapFrame->FltF10, &ContextFrame->FltF10,
sizeof(ULONGLONG) * 21);
//
// Set nonvolatile floating registers f2 - f9 in exception frame.
//
RtlMoveMemory(&ExceptionFrame->FltF2, &ContextFrame->FltF2,
sizeof(ULONGLONG) * 8);
//
// Set floating point control register in trap frame.
//
TrapFrame->Fpcr = SANITIZE_FPCR(ContextFrame->Fpcr, PreviousMode);
}
return;
}
#endif