299 lines
7.0 KiB
C
299 lines
7.0 KiB
C
|
// ----------------------------------------------------------------------------
|
|||
|
// Copyright (c) 1992 Olivetti
|
|||
|
//
|
|||
|
// File: eisaintr.c
|
|||
|
//
|
|||
|
// Description: EISA code interrupt related routines
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
#include "fwp.h"
|
|||
|
#include "oli2msft.h"
|
|||
|
#include "arceisa.h"
|
|||
|
#include "inc.h"
|
|||
|
#include "string.h"
|
|||
|
#include "debug.h"
|
|||
|
|
|||
|
|
|||
|
extern EISA_BUS_INFO EisaBusInfo[];
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// Declare Function Prototypes
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
EisaBeginCriticalSection
|
|||
|
(
|
|||
|
IN VOID
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaEndCriticalSection
|
|||
|
(
|
|||
|
IN VOID
|
|||
|
);
|
|||
|
|
|||
|
ARC_STATUS
|
|||
|
EisaProcessEndOfInterrupt
|
|||
|
(
|
|||
|
IN ULONG BusNumber,
|
|||
|
IN USHORT Irq
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN_ULONG
|
|||
|
EisaTestEisaInterrupt
|
|||
|
(
|
|||
|
IN ULONG BusNumber,
|
|||
|
IN USHORT Irq
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// General Function Prototypes
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
|
|||
|
ULONG
|
|||
|
StatusReg
|
|||
|
(
|
|||
|
IN ULONG,
|
|||
|
IN ULONG
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// General : Begin/End Critical Setction functions
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
ULONG NestedCounter = 0 ; // nested conter;
|
|||
|
ULONG StatusRegBuff = 0 ; // used to store the old ints status
|
|||
|
// bits 31-16 Reserved (0)
|
|||
|
// bits 15- 8 Specific interrupt mask
|
|||
|
// bits 7- 1 Reserved (0)
|
|||
|
// bit 0 General Interrupt mask
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaBeginCriticalSection:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function disables all the hardware interrupts
|
|||
|
// except for the EISA NMI interrupt. The old interrupt
|
|||
|
// status is saved for "EisaEndCriticalSection" routine.
|
|||
|
//
|
|||
|
// ARGUMENTS: none
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaBeginCriticalSection
|
|||
|
(
|
|||
|
IN VOID
|
|||
|
)
|
|||
|
{
|
|||
|
// Disable interrupts (except for the EISA NMI) and save the old interrupt
|
|||
|
// status only if no previous calls to this routine were made.
|
|||
|
// The first argument is "&" and the second is "|" with the status
|
|||
|
// register.
|
|||
|
|
|||
|
if ( !NestedCounter++ )
|
|||
|
{
|
|||
|
StatusRegBuff = StatusReg(~STATUS_INT_MASK, STATUS_EISA_NMI+STATUS_IE);
|
|||
|
}
|
|||
|
|
|||
|
// all done
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaEndCriticalSection:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function restores the hardware interrupt status
|
|||
|
// at the CPU level as it was before calling the
|
|||
|
// "EisaBeginCriticalSection" function.
|
|||
|
//
|
|||
|
// ARGUMENTS: none
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaEndCriticalSection
|
|||
|
(
|
|||
|
IN VOID
|
|||
|
)
|
|||
|
{
|
|||
|
// Restore the interrupts status only if NestedCounter equals zero.
|
|||
|
// The first argument is "&" and the second is "|" with the status
|
|||
|
// register.
|
|||
|
|
|||
|
if ( !--NestedCounter )
|
|||
|
{
|
|||
|
StatusReg(~STATUS_INT_MASK, StatusRegBuff & STATUS_INT_MASK);
|
|||
|
}
|
|||
|
|
|||
|
// all done
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaProcessEndOfInterrupt:
|
|||
|
//
|
|||
|
// DESCRIPTION: Because the EISA interrupts are masked at PIC
|
|||
|
// (8259A) level, this routine function doesn't need
|
|||
|
// to do anything.
|
|||
|
// It doesn't matter if the interrupt channel is level
|
|||
|
// or edge triggered, when the interrupt sources goes
|
|||
|
// away, the corrisponding bit within the interrupt
|
|||
|
// request register (IRR) is cleared.
|
|||
|
//
|
|||
|
// ARGUMENTS: BusNumber EISA bus number
|
|||
|
// Irq IRQ to process
|
|||
|
//
|
|||
|
// RETURN: ESUCCESS All done
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS: none
|
|||
|
//
|
|||
|
// GLOBALS: none
|
|||
|
//
|
|||
|
// NOTES: none
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
ARC_STATUS
|
|||
|
EisaProcessEndOfInterrupt
|
|||
|
(
|
|||
|
IN ULONG BusNumber,
|
|||
|
IN USHORT Irq
|
|||
|
)
|
|||
|
{
|
|||
|
// Return all done.
|
|||
|
|
|||
|
return ESUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaTestEisaInterrupt:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function checks if there is an interrupt pending
|
|||
|
// on the specified IRQ.
|
|||
|
//
|
|||
|
// ARGUMENTS: BusNumber EISA bus number
|
|||
|
// Irq IRQ to process
|
|||
|
//
|
|||
|
// RETURN: TRUE Interrupt is pending
|
|||
|
// FALSE Interrupt is not pending
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS: none
|
|||
|
//
|
|||
|
// GLOBALS: none
|
|||
|
//
|
|||
|
// NOTES: none
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN_ULONG
|
|||
|
EisaTestEisaInterrupt
|
|||
|
(
|
|||
|
IN ULONG BusNumber,
|
|||
|
IN USHORT Irq
|
|||
|
)
|
|||
|
{
|
|||
|
// define local variables
|
|||
|
|
|||
|
BOOLEAN_ULONG IntPending = FALSE; // assume no interrupt is pending
|
|||
|
PUCHAR PicPort; // PIC virtual address
|
|||
|
UCHAR PicMask; // to check the requested IRQ
|
|||
|
|
|||
|
// check the IRQ only if the input parameters are valid
|
|||
|
|
|||
|
// if ( EisaCheckBusNumber( BusNumber ) == ESUCCESS && Irq <= IRQ15 )
|
|||
|
if ( Irq <= IRQ15 )
|
|||
|
{
|
|||
|
// load the virtual address of the specified EISA I/O bus and
|
|||
|
// build the mask for checking the specified IRQ.
|
|||
|
|
|||
|
PicPort = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
|
|||
|
|
|||
|
if ( Irq < IRQ8 )
|
|||
|
{
|
|||
|
PicPort += PIC1; // the IRQ is on the 1st PIC
|
|||
|
PicMask = 1 << Irq; // set the mask
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
PicPort += PIC2; // the IRQ is on the 2nd PIC
|
|||
|
PicMask = 1 << (Irq - IRQ8); // set the mask
|
|||
|
}
|
|||
|
|
|||
|
// to check the spcified IRQ we need to send first an OCW3 command
|
|||
|
// to the PIC to request the interrupt request register (IRR).
|
|||
|
|
|||
|
WRITE_REGISTER_UCHAR( PicPort, OCW3_IRR );
|
|||
|
|
|||
|
EISA_IO_DELAY;
|
|||
|
|
|||
|
if ( READ_REGISTER_UCHAR(PicPort) & PicMask )
|
|||
|
{
|
|||
|
IntPending = TRUE; // interrupt is pending
|
|||
|
}
|
|||
|
}
|
|||
|
// return the specified IRQ status
|
|||
|
|
|||
|
return IntPending;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|