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.
396 lines
6.5 KiB
396 lines
6.5 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
Copyright (c) 1992, 1993 Digital Equipment Corporation
|
|
|
|
Module Name:
|
|
|
|
lxintsup.c
|
|
|
|
Abstract:
|
|
|
|
The module provides the interrupt support for LX3
|
|
|
|
Author:
|
|
|
|
Eric Rehm (DEC) 29-December-1993
|
|
|
|
Revision History:
|
|
|
|
Rewritten from ebintsup.c to lx3intsup.
|
|
|
|
|
|
--*/
|
|
|
|
|
|
#include "halp.h"
|
|
#include "eisa.h"
|
|
#include "ebsgdma.h"
|
|
#include "lx3.h"
|
|
#include "pcrtc.h"
|
|
|
|
|
|
extern BOOLEAN SioCStep;
|
|
|
|
#ifdef IDLE_PROCESSOR
|
|
ULONG HalpInterruptReceived;
|
|
BOOLEAN
|
|
PreHalpSioDispatch(
|
|
VOID
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Declare the interrupt handler for the PCI and ISA bus.
|
|
//
|
|
|
|
BOOLEAN
|
|
HalpSioDispatch(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// The following is the interrupt object used for DMA controller interrupts.
|
|
// DMA controller interrupts occur when a memory parity error occurs or a
|
|
// programming error occurs to the DMA controller.
|
|
//
|
|
|
|
KINTERRUPT HalpEisaNmiInterrupt;
|
|
|
|
//
|
|
// The following function initializes NMI handling.
|
|
//
|
|
|
|
VOID
|
|
HalpInitializeNMI(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// The following function is called when an ISA NMI occurs.
|
|
//
|
|
|
|
BOOLEAN
|
|
HalHandleNMI(
|
|
IN PKINTERRUPT Interrupt,
|
|
IN PVOID ServiceContext
|
|
);
|
|
|
|
|
|
BOOLEAN
|
|
HalpInitializePCIInterrupts (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the structures necessary for ISA & PCI operations
|
|
and connects the intermediate interrupt dispatcher.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
If the second level interrupt dispatcher is connected, then a value of
|
|
TRUE is returned. Otherwise, a value of FALSE is returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
KIRQL oldIrql;
|
|
|
|
|
|
//
|
|
// Initialize the EISA NMI interrupt.
|
|
//
|
|
|
|
HalpInitializeNMI();
|
|
|
|
|
|
//
|
|
// Directly connect the ISA interrupt dispatcher to the level for
|
|
// ISA bus interrupt.
|
|
//
|
|
// N.B. This vector is reserved for exclusive use by the HAL (see
|
|
// interrupt initialization.
|
|
//
|
|
|
|
#ifdef IDLE_PROCESSOR
|
|
PCR->InterruptRoutine[PIC_VECTOR] = PreHalpSioDispatch;
|
|
#else
|
|
PCR->InterruptRoutine[PIC_VECTOR] = HalpSioDispatch;
|
|
#endif
|
|
HalEnableSystemInterrupt(PIC_VECTOR, ISA_DEVICE_LEVEL, LevelSensitive);
|
|
|
|
|
|
//
|
|
// Intitialize interrupt controller
|
|
//
|
|
|
|
KeRaiseIrql(ISA_DEVICE_LEVEL, &oldIrql);
|
|
|
|
|
|
//
|
|
// Initialize the PCI-ISA bridge interrupt controller
|
|
//
|
|
|
|
HalpInitializeSioInterrupts();
|
|
|
|
//
|
|
// Restore IRQL level.
|
|
//
|
|
|
|
KeLowerIrql(oldIrql);
|
|
|
|
//
|
|
// Initialize the DMA mode registers to a default value.
|
|
// Disable all of the DMA channels except channel 4 which is the
|
|
// cascade of channels 0-3.
|
|
//
|
|
|
|
WRITE_PORT_UCHAR(
|
|
&((PEISA_CONTROL) HalpEisaControlBase)->Dma1BasePort.AllMask,
|
|
0x0F
|
|
);
|
|
|
|
WRITE_PORT_UCHAR(
|
|
&((PEISA_CONTROL) HalpEisaControlBase)->Dma2BasePort.AllMask,
|
|
0x0E
|
|
);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
VOID
|
|
HalpInitializeNMI(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called to intialize SIO NMI interrupts.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
--*/
|
|
{
|
|
UCHAR DataByte;
|
|
|
|
//
|
|
// Initialize the SIO NMI interrupt.
|
|
//
|
|
|
|
KeInitializeInterrupt( &HalpEisaNmiInterrupt,
|
|
HalHandleNMI,
|
|
NULL,
|
|
NULL,
|
|
EISA_NMI_VECTOR,
|
|
EISA_NMI_LEVEL,
|
|
EISA_NMI_LEVEL,
|
|
LevelSensitive,
|
|
FALSE,
|
|
0,
|
|
FALSE
|
|
);
|
|
|
|
//
|
|
// Don't fail if the interrupt cannot be connected.
|
|
//
|
|
|
|
KeConnectInterrupt( &HalpEisaNmiInterrupt );
|
|
|
|
//
|
|
// Clear the Eisa NMI disable bit. This bit is the high order of the
|
|
// NMI enable register.
|
|
//
|
|
|
|
DataByte = 0;
|
|
|
|
WRITE_PORT_UCHAR(
|
|
&((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable,
|
|
DataByte
|
|
);
|
|
|
|
}
|
|
|
|
BOOLEAN
|
|
HalHandleNMI(
|
|
IN PKINTERRUPT Interrupt,
|
|
IN PVOID ServiceContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called when an EISA NMI occurs. It print the appropriate
|
|
status information and bugchecks.
|
|
|
|
Arguments:
|
|
|
|
Interrupt - Supplies a pointer to the interrupt object
|
|
|
|
ServiceContext - Bug number to call bugcheck with.
|
|
|
|
Return Value:
|
|
|
|
Returns TRUE.
|
|
|
|
--*/
|
|
{
|
|
UCHAR StatusByte;
|
|
|
|
#ifdef IDLE_PROCESSOR
|
|
//
|
|
// Clear interrupt flag
|
|
//
|
|
|
|
HalpInterruptReceived = 0;
|
|
#endif
|
|
|
|
StatusByte =
|
|
READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);
|
|
|
|
if (StatusByte & 0x80) {
|
|
HalDisplayString ("NMI: Parity Check / Parity Error\n");
|
|
}
|
|
|
|
if (StatusByte & 0x40) {
|
|
HalDisplayString ("NMI: Channel Check / IOCHK\n");
|
|
}
|
|
|
|
//
|
|
// This is an Sio machine, no extnded nmi information, so just do it.
|
|
//
|
|
|
|
|
|
KeBugCheck(NMI_HARDWARE_FAILURE);
|
|
return(TRUE);
|
|
}
|
|
|
|
UCHAR
|
|
HalpAcknowledgeEisaInterrupt(
|
|
PVOID ServiceContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Acknowledge the EISA interrupt from the programmable interrupt controller.
|
|
Return the vector number of the highest priority pending interrupt.
|
|
|
|
Arguments:
|
|
|
|
ServiceContext - Service context of the interrupt service supplies
|
|
a pointer to the EISA interrupt acknowledge register.
|
|
|
|
Return Value:
|
|
|
|
Return the value of the highest priority pending interrupt.
|
|
|
|
--*/
|
|
{
|
|
UCHAR InterruptVector;
|
|
|
|
#ifdef IDLE_PROCESSOR
|
|
//
|
|
// Clear interrupt flag
|
|
//
|
|
|
|
HalpInterruptReceived = 0;
|
|
#endif
|
|
|
|
//
|
|
// Read the interrupt vector from the PIC.
|
|
//
|
|
|
|
InterruptVector = READ_PORT_UCHAR(ServiceContext);
|
|
|
|
return( InterruptVector );
|
|
|
|
}
|
|
|
|
VOID
|
|
HalpAcknowledgeClockInterrupt(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Acknowledge the clock interrupt from the interval timer. The interval
|
|
timer for EB66 comes from the Dallas real-time clock.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
|
|
#ifdef IDLE_PROCESSOR
|
|
//
|
|
// Clear interrupt flag
|
|
//
|
|
|
|
HalpInterruptReceived = 0;
|
|
#endif
|
|
|
|
//
|
|
// Acknowledge the clock interrupt by reading the control register C of
|
|
// the Real Time Clock.
|
|
//
|
|
|
|
HalpReadClockRegister( RTC_CONTROL_REGISTERC );
|
|
|
|
return;
|
|
}
|
|
|
|
#ifdef IDLE_PROCESSOR
|
|
BOOLEAN
|
|
PreHalpSioDispatch(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Acknowledge the PCI interrupt by clearing the interrupt flag, then
|
|
dispatch to the real PCI/SIO interrupt handler
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
|
|
//
|
|
// Clear interrupt flag
|
|
//
|
|
|
|
HalpInterruptReceived = 0;
|
|
|
|
return HalpSioDispatch();
|
|
|
|
}
|
|
#endif
|
|
|