windows-nt/Source/XPSP1/NT/base/boot/bd/ia64/trapc.c
2020-09-26 16:20:57 +08:00

276 lines
5.8 KiB
C
Raw Permalink 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.

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
trapc.c
Abstract:
This module implements the specific exception handlers for EM
exceptions. Called by the BdGenericExceptionHandler.
Author:
Bernard Lint 4-Apr-96
Environment:
Kernel mode only.
Revision History:
--*/
#include "bd.h"
typedef struct _BREAK_INST {
union {
struct {
ULONGLONG qp: 6;
ULONGLONG imm20: 20;
ULONGLONG x: 1;
ULONGLONG x6: 6;
ULONGLONG x3: 3;
ULONGLONG i: 1;
ULONGLONG Op: 4;
ULONGLONG Rsv: 23;
} i_field;
ULONGLONG Ulong64;
} u;
} BREAK_INST;
ULONG
BdExtractImmediate (
IN ULONGLONG Iip,
IN ULONG SlotNumber
)
/*++
Routine Description:
Extract immediate operand from break instruction.
Arguments:
Iip - Bundle address of instruction
SlotNumber - Slot of break instruction within bundle
Return Value:
Value of immediate operand.
--*/
{
PULONGLONG BundleAddress;
ULONGLONG BundleLow;
ULONGLONG BundleHigh;
BREAK_INST BreakInst;
ULONG Imm21;
BundleAddress = (PULONGLONG)Iip;
BundleLow = *BundleAddress;
BundleHigh = *(BundleAddress+1);
//
// Align instruction
//
switch (SlotNumber) {
case 0:
BreakInst.u.Ulong64 = BundleLow >> 5;
break;
case 1:
BreakInst.u.Ulong64 = (BundleLow >> 46) | (BundleHigh << 18);
break;
case 2:
BreakInst.u.Ulong64 = (BundleHigh >> 23);
break;
}
//
// Extract immediate value
//
Imm21 = (ULONG)(BreakInst.u.i_field.i<<20) | (ULONG)(BreakInst.u.i_field.imm20);
return Imm21;
}
BOOLEAN
BdOtherBreakException (
IN PKTRAP_FRAME TrapFrame
)
/*++
Routine Description:
Handler for break exception other than the ones for fast and
normal system calls. This includes debug break points.
Arguments:
TrapFrame - Pointer to the trap frame.
Return Value:
NT status code.
--*/
{
PEXCEPTION_RECORD ExceptionRecord;
ULONG BreakImmediate;
ISR Isr;
BreakImmediate = (ULONG)(TrapFrame->StIIM);
//
// Handle break.b case
//
if (BreakImmediate == 0) {
Isr.ull = TrapFrame->StISR;
BreakImmediate = BdExtractImmediate(TrapFrame->StIIP,
(ULONG)Isr.sb.isr_ei);
TrapFrame->StIIM = BreakImmediate;
}
//
// Initialize exception record
//
ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
ExceptionRecord->ExceptionAddress =
(PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
ExceptionRecord->ExceptionFlags = 0;
ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)NULL;
ExceptionRecord->NumberParameters = 5;
ExceptionRecord->ExceptionInformation[0] = 0;
ExceptionRecord->ExceptionInformation[1] = 0;
ExceptionRecord->ExceptionInformation[2] = 0;
ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
switch (BreakImmediate) {
case KERNEL_BREAKPOINT:
case USER_BREAKPOINT:
case BREAKPOINT_PRINT:
case BREAKPOINT_PROMPT:
case BREAKPOINT_STOP:
case BREAKPOINT_LOAD_SYMBOLS:
case BREAKPOINT_UNLOAD_SYMBOLS:
case BREAKPOINT_BREAKIN:
ExceptionRecord->ExceptionCode = STATUS_BREAKPOINT;
ExceptionRecord->ExceptionInformation[0] = BreakImmediate;
break;
case INTEGER_DIVIDE_BY_ZERO_BREAK:
ExceptionRecord->ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
break;
case INTEGER_OVERFLOW_BREAK:
ExceptionRecord->ExceptionCode = STATUS_INTEGER_OVERFLOW;
break;
case MISALIGNED_DATA_BREAK:
ExceptionRecord->ExceptionCode = STATUS_DATATYPE_MISALIGNMENT;
break;
case RANGE_CHECK_BREAK:
case NULL_POINTER_DEFERENCE_BREAK:
case DECIMAL_OVERFLOW_BREAK:
case DECIMAL_DIVIDE_BY_ZERO_BREAK:
case PACKED_DECIMAL_ERROR_BREAK:
case INVALID_ASCII_DIGIT_BREAK:
case INVALID_DECIMAL_DIGIT_BREAK:
case PARAGRAPH_STACK_OVERFLOW_BREAK:
default:
#if 0
#if DBG
InbvDisplayString ("BdOtherBreakException: Unknown break code.\n");
#endif // DBG
#endif
ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
break;
}
return TRUE;
}
BOOLEAN
BdSingleStep (
IN PKTRAP_FRAME TrapFrame
)
/*++
Routine Description:
Handler for single step trap. An instruction was successfully
executed and the PSR.ss bit is 1.
Arguments:
TrapFrame - Pointer to the trap frame.
Return Value:
None.
Notes:
ISR.ei bits indicate which instruction caused the exception.
ISR.code{3:0} = 1000
--*/
{
PEXCEPTION_RECORD ExceptionRecord;
ULONG IpsrRi;
//
// Initialize the exception record
//
ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
//
// We only want the low order 2 bits so typecast to ULONG
//
IpsrRi = (ULONG)(TrapFrame->StIPSR >> PSR_RI) & 0x3;
ExceptionRecord->ExceptionAddress =
(PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP, IpsrRi);
ExceptionRecord->ExceptionFlags = 0;
ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)NULL;
ExceptionRecord->NumberParameters = 5;
ExceptionRecord->ExceptionInformation[0] = 0;
ExceptionRecord->ExceptionInformation[1] = 0; // 0 for traps
ExceptionRecord->ExceptionInformation[2] = 0;
ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
ExceptionRecord->ExceptionCode = STATUS_SINGLE_STEP;
return TRUE;
}