Windows NT 4.0 source code leak
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

// 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;
}
}