summaryrefslogblamecommitdiffstats
path: root/private/ntos/fw/mips/eisaintr.c
blob: 176d9f6394f26a8cfad14e486f2a1694788c46fe (plain) (tree)









































































































































































































































































































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