NT4/private/ntos/nthals/hallx3/alpha/lxintsup.c
2020-09-30 17:12:29 +02:00

397 lines
6.5 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.

/*++
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