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