mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
284 lines
7.9 KiB
284 lines
7.9 KiB
// TITLE("Manipulate Interrupt Request Level")
|
|
//++
|
|
//
|
|
// Copyright (c) 1990 Microsoft Corporation
|
|
// Copyright (c) 1996 International Business Machines Corporation
|
|
// Copyright 1994 MOTOROLA, INC. All Rights Reserved. This file
|
|
// contains copyrighted material. Use of this file is restricted
|
|
// by the provisions of a Motorola Software License Agreement.
|
|
//
|
|
// Module Name:
|
|
//
|
|
// PXIRQL.C
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements the code necessary to lower and raise the current
|
|
// Interrupt Request Level (IRQL).
|
|
//
|
|
//
|
|
// Author:
|
|
//
|
|
// Jim Wooldridge (IBM)
|
|
// Steve Johns (Motorola)
|
|
//
|
|
// Environment:
|
|
//
|
|
// Kernel mode only.
|
|
//
|
|
// Revision History:
|
|
// 22-Feb-94 Steve Johns (Motorola)
|
|
// KeRaiseIrql - Disabled interrupts at PIC if IRQL >= DEVICE_LEVEL
|
|
// KeLowerIrql - Enabled interrupts at PIC if IRQL < DEVICE_LEVEL
|
|
// 15-Apr-94 Jim Wooldridge
|
|
// Added irql interrupt mask table and expanded irql range from (0-8)
|
|
// to (0-31).
|
|
//
|
|
//--
|
|
|
|
#include "halp.h"
|
|
#include "eisa.h"
|
|
|
|
#define ISA_CONTROL ((PEISA_CONTROL) HalpIoControlBase)
|
|
extern UCHAR HalpSioInterrupt1Mask;
|
|
extern UCHAR HalpSioInterrupt2Mask;
|
|
extern BOOLEAN HalpProfilingActive;
|
|
|
|
UCHAR VectorToIrqlTable[] = { MAXIMUM_DEVICE_LEVEL, // irq 0
|
|
26, // irq 1
|
|
25, // irq 2
|
|
16, // irq 3
|
|
15, // irq 4
|
|
14, // irq 5
|
|
13, // irq 6
|
|
12, // irq 7
|
|
24, // irq 8
|
|
23, // irq 9
|
|
22, // irq 10
|
|
21, // irq 11
|
|
20, // irq 12
|
|
19, // irq 13
|
|
18, // irq 14
|
|
17 // irq 15
|
|
};
|
|
|
|
|
|
//
|
|
// Initialize the 8259 irql mask table
|
|
//
|
|
|
|
USHORT Halp8259MaskTable[] = { 0x0000, // irql0 Low level
|
|
0x0000, // irql1 APC
|
|
0x0000, // irql2 Dispatch
|
|
0x0000, // irql3
|
|
0x0000, // irql4
|
|
0x0000, // irql5
|
|
0x0000, // irql6
|
|
0x0000, // irql7
|
|
0x0000, // irql8
|
|
0x0000, // irql9
|
|
0x0000, // irql10
|
|
0x0000, // irql11
|
|
0x0080, // irql12 parallel
|
|
0x00C0, // irql13 floppy
|
|
0x00E0, // irql14 parallel
|
|
0x00F0, // irql15 com 1
|
|
0x00F8, // irql16 com 2
|
|
0x80F8, // irql17 pci slot
|
|
0xC0F8, // irql18 isa slot
|
|
0xE0F8, // irql19 scsi
|
|
0xF0F8, // irql20 mouse
|
|
0xF8F8, // irql21 isa slot
|
|
0xFCF8, // irql22 audio
|
|
0xFEF8, // irql23 isa slot
|
|
0xFFF8, // irql24 rtc
|
|
0xFFFA, // irql25 cascade
|
|
0xFFFA, // irql26 kb
|
|
0xFFFB, // irql27 timer 1/ profile
|
|
0xFFFF, // irql28 clock level
|
|
0xFFFF, // irql29
|
|
0xFFFF, // irql30
|
|
0xFFFF // irql31 High level
|
|
};
|
|
|
|
|
|
#define IRQ0 1
|
|
|
|
VOID
|
|
KiDispatchSoftwareInterrupt(
|
|
VOID
|
|
);
|
|
|
|
|
|
//
|
|
// VOID
|
|
// KeLowerIrql (
|
|
// KIRQL NewIrql
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function lowers the current IRQL to the specified value.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// NewIrql - Supplies the new IRQL value.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
|
|
VOID
|
|
KeLowerIrql(
|
|
KIRQL NewIrql
|
|
)
|
|
|
|
{
|
|
KIRQL OldIrql;
|
|
PUCHAR PIC_Address;
|
|
UCHAR PIC_Mask;
|
|
|
|
|
|
OldIrql = PCR->CurrentIrql;
|
|
|
|
//
|
|
// If this is a software to software transition don't change hardware
|
|
// interrupt state
|
|
//
|
|
|
|
if (OldIrql > DISPATCH_LEVEL) {
|
|
|
|
HalpDisableInterrupts();
|
|
PCR->CurrentIrql = NewIrql;
|
|
|
|
//
|
|
// If old IRQL is < CLOCK2_LEVEL then interrupt are enabled
|
|
// in the MSR but the 8259 mask must be updated. If not, then
|
|
// interrupts need to be enabled, however the 8259 does not need to
|
|
// be updated.
|
|
//
|
|
|
|
if (NewIrql < CLOCK2_LEVEL) {
|
|
|
|
|
|
if (OldIrql < CLOCK2_LEVEL ) {
|
|
|
|
|
|
//
|
|
// Get contoller 1 interrupt mask
|
|
//
|
|
|
|
HALPCR->HardPriority = NewIrql;
|
|
|
|
PIC_Mask = HalpSioInterrupt1Mask | (Halp8259MaskTable[NewIrql] & 0x00FF);
|
|
PIC_Address = &(ISA_CONTROL->Interrupt1ControlPort1);
|
|
WRITE_REGISTER_UCHAR(PIC_Address, PIC_Mask);
|
|
|
|
//
|
|
// Get contoller 2 interrupt mask
|
|
//
|
|
|
|
PIC_Mask = HalpSioInterrupt2Mask | (Halp8259MaskTable[NewIrql] >> 8 );
|
|
PIC_Address = &(ISA_CONTROL->Interrupt2ControlPort1);
|
|
WRITE_REGISTER_UCHAR(PIC_Address, PIC_Mask);
|
|
}
|
|
HalpEnableInterrupts();
|
|
|
|
}
|
|
}
|
|
else {
|
|
PCR->CurrentIrql = NewIrql;
|
|
}
|
|
|
|
//
|
|
// check for DPC's
|
|
|
|
if ((NewIrql < DISPATCH_LEVEL) && PCR->SoftwareInterrupt)
|
|
KiDispatchSoftwareInterrupt();
|
|
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
//
|
|
// VOID KeRaiseIrql (
|
|
// KIRQL NewIrql,
|
|
// PKIRQL OldIrql
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function raises the current IRQL to the specified value and returns
|
|
// the old IRQL value.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// NewIrql - Supplies the new IRQL value.
|
|
//
|
|
// OldIrql - Supplies a pointer to a variable that recieves the old
|
|
// IRQL value.
|
|
//
|
|
|
|
VOID
|
|
KeRaiseIrql(
|
|
IN KIRQL NewIrql,
|
|
OUT PKIRQL OldIrql
|
|
)
|
|
|
|
{
|
|
PUCHAR PIC_Address;
|
|
UCHAR PIC_Mask;
|
|
|
|
|
|
|
|
//
|
|
// If this is a software to software transition don't change hardware
|
|
// interrupt state
|
|
//
|
|
|
|
if (NewIrql > DISPATCH_LEVEL) {
|
|
|
|
HalpDisableInterrupts();
|
|
*OldIrql = PCR->CurrentIrql;
|
|
PCR->CurrentIrql = NewIrql;
|
|
|
|
//
|
|
// If new irql is >= CLOCK2_LEVEL disable interrupts in the MSR but
|
|
// don't touch the 8259's. If not, leave interrupts enabled and
|
|
// update the 8259's
|
|
//
|
|
|
|
if (NewIrql < CLOCK2_LEVEL) {
|
|
|
|
HALPCR->HardPriority = NewIrql;
|
|
|
|
//
|
|
// Get controller 1 interrupt mask
|
|
//
|
|
|
|
PIC_Address = &(ISA_CONTROL->Interrupt1ControlPort1);
|
|
PIC_Mask = HalpSioInterrupt1Mask | (Halp8259MaskTable[NewIrql] & 0x00FF);
|
|
WRITE_REGISTER_UCHAR(PIC_Address, PIC_Mask);
|
|
|
|
//
|
|
// Get controller 2 interrupt mask
|
|
//
|
|
|
|
PIC_Mask = HalpSioInterrupt2Mask | (Halp8259MaskTable[NewIrql] >> 8);
|
|
PIC_Address = &(ISA_CONTROL->Interrupt2ControlPort1);
|
|
WRITE_REGISTER_UCHAR(PIC_Address, PIC_Mask);
|
|
|
|
HalpEnableInterrupts();
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
*OldIrql = PCR->CurrentIrql;
|
|
PCR->CurrentIrql = NewIrql;
|
|
}
|
|
|
|
}
|