3676 lines
74 KiB
C
3676 lines
74 KiB
C
|
// ----------------------------------------------------------------------------
|
|||
|
// Copyright (c) 1992 Olivetti
|
|||
|
//
|
|||
|
// File: eisapod.c
|
|||
|
//
|
|||
|
// Description:
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
#include "fwp.h"
|
|||
|
#include "oli2msft.h"
|
|||
|
#include "arceisa.h"
|
|||
|
#include "inc.h"
|
|||
|
#include "string.h"
|
|||
|
#include "debug.h"
|
|||
|
#include "eisastr.h"
|
|||
|
|
|||
|
extern EISA_BUS_INFO EisaBusInfo[];
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// Define Function Prototypes
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaBusPod
|
|||
|
(
|
|||
|
IN ULONG BusNumber
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaIntPod
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaPicIni
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaPicRegTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaClearPendingInts
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaPod
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaMaskTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaPageTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaAddressTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaCountTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaStopTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaDmaIni
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaOtherPod
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaNmiTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaNmiHandlerTest
|
|||
|
(
|
|||
|
IN ULONG Couse
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaNmiHandler
|
|||
|
(
|
|||
|
IN ULONG Couse
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaParityError
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaIoChkError
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN ULONG Slots
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaBusTimeoutError
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN ULONG Slots
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaSlaveTimeoutError
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN ULONG Slots
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaRefreshTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaPort61Test
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaTimer1Test
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaTimer2Test
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// Define EISA Function Prototypes
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
|
|||
|
VOID
|
|||
|
EisaClearPendingInt
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo,
|
|||
|
IN USHORT Irq
|
|||
|
);
|
|||
|
|
|||
|
UCHAR
|
|||
|
EisaAckInt
|
|||
|
(
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaSendSpecificEoi
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN USHORT Irq
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaDisableParityIoCheck
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaEnableParityIoCheck
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaDisableInt
|
|||
|
(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaDisableNmi
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaEnableNmi
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaCheckReg
|
|||
|
(
|
|||
|
IN PUCHAR Port,
|
|||
|
IN UCHAR DataMask
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaCheckDeepReg
|
|||
|
(
|
|||
|
IN PUCHAR Port
|
|||
|
);
|
|||
|
|
|||
|
UCHAR
|
|||
|
EisaReadRtc
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN ULONG RtcIndex
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
EisaOutUchar
|
|||
|
(
|
|||
|
IN PUCHAR Addr,
|
|||
|
IN UCHAR Value
|
|||
|
);
|
|||
|
|
|||
|
UCHAR
|
|||
|
EisaInUchar
|
|||
|
(
|
|||
|
IN PUCHAR Addr
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// Define Global Variables
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
|
|||
|
EISA_DMA_REGS_TEST EisaDmaRegsTest[ EISA_DMAS ] =
|
|||
|
{
|
|||
|
{ DMA_ADDR_0, DMA_PAGE_0, DMA_HPAGE_0,
|
|||
|
DMA_COUNT_0, DMA_HCOUNT_0, DMA_STOP_0 },
|
|||
|
{ DMA_ADDR_1, DMA_PAGE_1, DMA_HPAGE_1,
|
|||
|
DMA_COUNT_1, DMA_HCOUNT_1, DMA_STOP_1 },
|
|||
|
{ DMA_ADDR_2, DMA_PAGE_2, DMA_HPAGE_2,
|
|||
|
DMA_COUNT_2, DMA_HCOUNT_2, DMA_STOP_2 },
|
|||
|
{ DMA_ADDR_3, DMA_PAGE_3, DMA_HPAGE_3,
|
|||
|
DMA_COUNT_3, DMA_HCOUNT_3, DMA_STOP_3 },
|
|||
|
{ DMA_ADDR_4, DMA_PAGE_RFR, 0,
|
|||
|
DMA_COUNT_4, 0, 0 },
|
|||
|
{ DMA_ADDR_5, DMA_PAGE_5, DMA_HPAGE_5,
|
|||
|
DMA_COUNT_5, DMA_HCOUNT_5, DMA_STOP_5 },
|
|||
|
{ DMA_ADDR_6, DMA_PAGE_6, DMA_HPAGE_6,
|
|||
|
DMA_COUNT_6, DMA_HCOUNT_6, DMA_STOP_6 },
|
|||
|
{ DMA_ADDR_7, DMA_PAGE_7, DMA_HPAGE_7,
|
|||
|
DMA_COUNT_7, DMA_HCOUNT_7, DMA_STOP_7 }
|
|||
|
};
|
|||
|
|
|||
|
EISA_DMA_CTRL_TEST EisaDmaCtrlTest[ 2 ] =
|
|||
|
{
|
|||
|
{DMA_MASK_CLR03, DMA_MASKS03, DMA_1MASK03, DMA_MASK_STAT03, DMA_CHAIN03},
|
|||
|
{DMA_MASK_CLR47, DMA_MASKS47, DMA_1MASK47, DMA_MASK_STAT47, DMA_CHAIN47}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
BOOLEAN EisaNmiFlag; // for NMI testing
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaBusPod:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function initializes the hardware of the
|
|||
|
// specified EISA bus.
|
|||
|
//
|
|||
|
// ARGUMENTS: BusNumber EISA bus number
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaBusPod
|
|||
|
(
|
|||
|
IN ULONG BusNumber
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN IniOk = TRUE; // initialization status
|
|||
|
PEISA_DMA_INFO pDmaInfo; // DMA info pointer
|
|||
|
PEISA_INT_INFO pIntInfo; // INT info pointer
|
|||
|
PEISA_PORT_INFO pPortInfo; // PORT info pointer
|
|||
|
PUCHAR EisaIoStart; // EISA I/O virtual address
|
|||
|
|
|||
|
PRINTDBG("EisaBusPod\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// initialize variables
|
|||
|
//
|
|||
|
|
|||
|
pDmaInfo = EisaBusInfo[ BusNumber ].DmaInfo;
|
|||
|
pIntInfo = EisaBusInfo[ BusNumber ].IntInfo;
|
|||
|
pPortInfo = EisaBusInfo[ BusNumber ].PortInfo;
|
|||
|
// EisaIoStart = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
|
|||
|
EisaIoStart = EISA_IO_VIRTUAL_BASE; // TEMPTEMP
|
|||
|
|
|||
|
//
|
|||
|
// perform any PIC testing and initialization
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaIntPod( EisaIoStart, pIntInfo ) )
|
|||
|
{
|
|||
|
IniOk = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// perform any DMA testing and initialization
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaDmaPod( EisaIoStart, pDmaInfo ) )
|
|||
|
{
|
|||
|
IniOk = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// perform any other port testing and initialization
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaOtherPod( EisaIoStart, pPortInfo ) )
|
|||
|
{
|
|||
|
IniOk = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// return status
|
|||
|
//
|
|||
|
|
|||
|
return IniOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaIntPod:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests and initializes the PIC for the
|
|||
|
// specified EISA bus.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pIntInfo Interrupt info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaIntPod
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaIntPod\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// if ini already done, return status
|
|||
|
//
|
|||
|
|
|||
|
if ( pIntInfo->Flags.IniDone )
|
|||
|
{
|
|||
|
return (BOOLEAN)(pIntInfo->Flags.Error);
|
|||
|
}
|
|||
|
pIntInfo->Flags.Error = 1; // be pessimistic
|
|||
|
|
|||
|
//
|
|||
|
// first part of checkpoint
|
|||
|
//
|
|||
|
|
|||
|
EisaCheckpointFirstFase( EisaPic );
|
|||
|
|
|||
|
//
|
|||
|
// disable EISA PICs interrupt chain
|
|||
|
//
|
|||
|
|
|||
|
EisaDisableInt();
|
|||
|
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
//
|
|||
|
// initialize PICs
|
|||
|
//
|
|||
|
|
|||
|
EisaPicIni( EisaIoStart, pIntInfo );
|
|||
|
|
|||
|
//
|
|||
|
// test registers
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaPicRegTest( EisaIoStart, pIntInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// clear any pending interrupt
|
|||
|
//
|
|||
|
|
|||
|
else if ( !EisaClearPendingInts( EisaIoStart, pIntInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// all done
|
|||
|
//
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
pIntInfo->IrqPresent = 0;
|
|||
|
pIntInfo->IrqShareable = 0;
|
|||
|
pIntInfo->IrqLevel = 0;
|
|||
|
pIntInfo->Flags.Error = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
while ( EisaCheckpointFinalFase( EisaPic,
|
|||
|
pIntInfo->Flags.Error ? FALSE : TRUE ));
|
|||
|
|
|||
|
//
|
|||
|
// return to caller
|
|||
|
//
|
|||
|
|
|||
|
pIntInfo->Flags.IniDone = 1;
|
|||
|
return !(BOOLEAN)(pIntInfo->Flags.Error);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaPicIni:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function initializes the PICs of the specified
|
|||
|
// EISA bus.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pIntInfo Interrupt info pointer
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaPicIni
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
)
|
|||
|
{
|
|||
|
PUCHAR Pic1Port1, Pic1Port2, Pic2Port1, Pic2Port2;
|
|||
|
|
|||
|
|
|||
|
PRINTDBG("EisaPicIni\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// initialize variables
|
|||
|
//
|
|||
|
|
|||
|
Pic1Port1 = EisaIoStart + PIC1;
|
|||
|
Pic1Port2 = EisaIoStart + PIC1 + 1;
|
|||
|
Pic2Port1 = EisaIoStart + PIC2;
|
|||
|
Pic2Port2 = EisaIoStart + PIC2 + 1;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the EISA interrupt controller. There are two cascaded
|
|||
|
// interrupt controllers, each of which must initialized with 4 initialize
|
|||
|
// control words.
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Pic1Port1, 0x11 );
|
|||
|
EisaOutUchar( Pic2Port1, 0x11 );
|
|||
|
|
|||
|
//
|
|||
|
// The second intitialization control word sets the iterrupt vector to
|
|||
|
// 0-15.
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Pic1Port2, 0x00 );
|
|||
|
EisaOutUchar( Pic2Port2, 0x08 );
|
|||
|
|
|||
|
//
|
|||
|
// The thrid initialization control word set the controls for slave mode.
|
|||
|
// The master ICW3 uses bit position and the slave ICW3 uses a numberic.
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Pic1Port2, 0x04 );
|
|||
|
EisaOutUchar( Pic2Port2, 0x02 );
|
|||
|
|
|||
|
//
|
|||
|
// The fourth initialization control word is used to specify normal
|
|||
|
// end-of-interrupt mode and not special-fully-nested mode.
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Pic1Port2, 0x01 );
|
|||
|
EisaOutUchar( Pic2Port2, 0x01 );
|
|||
|
|
|||
|
//
|
|||
|
// Mask all the interrupts.
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Pic1Port2, 0xFF );
|
|||
|
EisaOutUchar( Pic2Port2, 0xFF );
|
|||
|
|
|||
|
//
|
|||
|
// set all interrupts to edge sensitive
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + PIC1_ELCR, 0 );
|
|||
|
EisaOutUchar( EisaIoStart + PIC2_ELCR, 0 );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaPicRegTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function performs a test on the PIC registers.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pIntInfo Interrupt info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE all correct
|
|||
|
// FALSE error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaPicRegTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// initialize variables
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN RegOk = FALSE; // be pessimistic
|
|||
|
|
|||
|
PRINTDBG("EisaPicRegTest\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// check mask of 1st PIC
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaCheckReg( EisaIoStart + PIC1_MASK, 0xFF ));
|
|||
|
|
|||
|
//
|
|||
|
// check mask of 2nd PIC
|
|||
|
//
|
|||
|
|
|||
|
else if ( !EisaCheckReg( EisaIoStart + PIC2_MASK, 0xFF ));
|
|||
|
|
|||
|
//
|
|||
|
// check ELCR 1, but skip bits 0, 1 and 2 (they are reserved)
|
|||
|
//
|
|||
|
|
|||
|
else if ( !EisaCheckReg( EisaIoStart + PIC1_ELCR, 0xF8 ));
|
|||
|
|
|||
|
//
|
|||
|
// check ELCR 2, but skip bits 0 and 5 (they are reserved)
|
|||
|
//
|
|||
|
|
|||
|
else if ( !EisaCheckReg( EisaIoStart + PIC2_ELCR, 0xDE ));
|
|||
|
|
|||
|
//
|
|||
|
// if we got here, everything is fine
|
|||
|
//
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
EisaOutUchar( EisaIoStart + PIC1_MASK, 0xFF );
|
|||
|
EisaOutUchar( EisaIoStart + PIC2_MASK, 0xFF );
|
|||
|
EisaOutUchar( EisaIoStart + PIC1_ELCR, 0 );
|
|||
|
EisaOutUchar( EisaIoStart + PIC2_ELCR, 0 );
|
|||
|
RegOk = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
return RegOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaClearPendingInts:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function cleares any pending interrupt at
|
|||
|
// the CPU level.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pIntInfo Interrupt info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE all correct
|
|||
|
// FALSE error
|
|||
|
//
|
|||
|
// ASSUMPTIONS: interrupts disabled, PIC lines masked and
|
|||
|
// all the IRQ lines are edge triggered.
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaClearPendingInts
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// initialize variables
|
|||
|
//
|
|||
|
|
|||
|
UCHAR Irr; // interrupt request register
|
|||
|
UCHAR Isr; // interrupt service register
|
|||
|
USHORT Irq; // interrupt level
|
|||
|
PUCHAR PicPort; // I/O address
|
|||
|
|
|||
|
PRINTDBG("EisaClearPendingInts\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//--------------------------------------------------
|
|||
|
// send a specific EOI for each in service interrupt
|
|||
|
//--------------------------------------------------
|
|||
|
|
|||
|
//
|
|||
|
// read ISR PIC1
|
|||
|
//
|
|||
|
|
|||
|
PicPort = EisaIoStart + PIC1;
|
|||
|
EisaOutUchar( PicPort, OCW3_ISR );
|
|||
|
Isr = EisaInUchar( PicPort );
|
|||
|
|
|||
|
//
|
|||
|
// send SEOI for each interrupt that was in service
|
|||
|
//
|
|||
|
|
|||
|
for ( Irq=IRQ0; Isr; Irq++, Isr >>= 1 )
|
|||
|
{
|
|||
|
//
|
|||
|
// check if this IRQ was in service
|
|||
|
//
|
|||
|
|
|||
|
if ( !(Isr & 0x1) )
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// send a specific and of interrupt
|
|||
|
//
|
|||
|
|
|||
|
EisaSendSpecificEoi( EisaIoStart, Irq );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// read ISR PIC2
|
|||
|
//
|
|||
|
|
|||
|
PicPort = EisaIoStart + PIC2;
|
|||
|
EisaOutUchar( PicPort, OCW3_ISR );
|
|||
|
Isr = EisaInUchar( PicPort );
|
|||
|
|
|||
|
//
|
|||
|
// send SEOI for each interrupt that was in service
|
|||
|
//
|
|||
|
|
|||
|
for ( Irq=IRQ8; Isr; Irq++, Isr >>= 1 )
|
|||
|
{
|
|||
|
//
|
|||
|
// check if this IRQ was in service
|
|||
|
//
|
|||
|
|
|||
|
if ( !(Isr & 0x1) )
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// send a specific and of interrupt
|
|||
|
//
|
|||
|
|
|||
|
EisaSendSpecificEoi( EisaIoStart, Irq );
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------
|
|||
|
// reset all the pending interrupt in the EISA bus
|
|||
|
//--------------------------------------------------
|
|||
|
|
|||
|
//
|
|||
|
// read IRR PIC1
|
|||
|
//
|
|||
|
|
|||
|
PicPort = EisaIoStart + PIC1;
|
|||
|
EisaOutUchar( PicPort, OCW3_IRR );
|
|||
|
|
|||
|
// don't play with IRQ 0, 1 and 2
|
|||
|
|
|||
|
Irr = EisaInUchar( PicPort ) & 0xF8;
|
|||
|
|
|||
|
//
|
|||
|
// clear any PIC1 pending interrupt
|
|||
|
//
|
|||
|
|
|||
|
for ( Irq=IRQ0; Irr; Irq++, Irr >>= 1 )
|
|||
|
{
|
|||
|
//
|
|||
|
// check if this IRQ was pending
|
|||
|
//
|
|||
|
|
|||
|
if ( !(Irr & 0x1) )
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// reset the specified IRQ
|
|||
|
//
|
|||
|
|
|||
|
EisaClearPendingInt( EisaIoStart, pIntInfo, Irq );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// read IRR PIC2
|
|||
|
//
|
|||
|
|
|||
|
PicPort = EisaIoStart + PIC2;
|
|||
|
EisaOutUchar( PicPort, OCW3_IRR );
|
|||
|
|
|||
|
// don't play with IRQ 8
|
|||
|
|
|||
|
Irr = EisaInUchar( PicPort ) & 0xFE;
|
|||
|
|
|||
|
//
|
|||
|
// clear any PIC1 pending interrupt
|
|||
|
//
|
|||
|
|
|||
|
for ( Irq=IRQ8; Irr; Irq++, Irr >>= 1 )
|
|||
|
{
|
|||
|
//
|
|||
|
// check if this IRQ was pending
|
|||
|
//
|
|||
|
|
|||
|
if ( !(Irr & 0x1) )
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// reset the specifed IRQ
|
|||
|
//
|
|||
|
|
|||
|
EisaClearPendingInt( EisaIoStart, pIntInfo, Irq );
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------
|
|||
|
// error if it is possible to acknowledge an interrupt
|
|||
|
//----------------------------------------------------
|
|||
|
|
|||
|
EisaAckInt( pIntInfo );
|
|||
|
|
|||
|
//
|
|||
|
// read the ISR
|
|||
|
//
|
|||
|
|
|||
|
PicPort = EisaIoStart + PIC1;
|
|||
|
EisaOutUchar( PicPort, OCW3_ISR );
|
|||
|
|
|||
|
return EisaInUchar( PicPort ) ? FALSE : TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDmaPod:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests and initializes the DMA for the
|
|||
|
// specified EISA bus.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pDmaInfo DMA info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaPod
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaDmaPod\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// if ini already done, return status
|
|||
|
//
|
|||
|
|
|||
|
if ( pDmaInfo->Flags.IniDone )
|
|||
|
{
|
|||
|
return (BOOLEAN)(pDmaInfo->Flags.Error);
|
|||
|
}
|
|||
|
pDmaInfo->Flags.Error = 1; // be pessimistic
|
|||
|
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
//
|
|||
|
// first part of checkpoint
|
|||
|
//
|
|||
|
|
|||
|
EisaCheckpointFirstFase( EisaDma );
|
|||
|
|
|||
|
//
|
|||
|
// Clear the DMA controllers and disable all the channels.
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + DMA_MASTER_CLR03, 0);
|
|||
|
EisaOutUchar( EisaIoStart + DMA_COMMAND03, 4); // Set channel 0-3 disable
|
|||
|
EisaOutUchar( EisaIoStart + DMA_MASTER_CLR47, 0);
|
|||
|
EisaOutUchar( EisaIoStart + DMA_COMMAND47, 4); // Set channel 4-7 disable
|
|||
|
|
|||
|
//
|
|||
|
// check mask register
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaDmaMaskTest( EisaIoStart, pDmaInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// check the low and high page
|
|||
|
//
|
|||
|
|
|||
|
else if ( !EisaDmaPageTest( EisaIoStart, pDmaInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// check the base/current address register
|
|||
|
//
|
|||
|
|
|||
|
else if ( !EisaDmaAddressTest( EisaIoStart, pDmaInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// check the count register
|
|||
|
//
|
|||
|
|
|||
|
else if ( !EisaDmaCountTest( EisaIoStart, pDmaInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// check stop register
|
|||
|
//
|
|||
|
|
|||
|
else if ( !EisaDmaStopTest( EisaIoStart, pDmaInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// if we got here everything is fine
|
|||
|
//
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
EisaDmaIni( EisaIoStart, pDmaInfo );
|
|||
|
pDmaInfo->Flags.Error = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
while ( EisaCheckpointFinalFase( EisaDma,
|
|||
|
pDmaInfo->Flags.Error ? FALSE : TRUE ));
|
|||
|
//
|
|||
|
// return to caller
|
|||
|
//
|
|||
|
|
|||
|
pDmaInfo->Flags.IniDone = 1;
|
|||
|
return !(BOOLEAN)(pDmaInfo->Flags.Error);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDmaMaskTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests the mask register.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pDmaInfo DMA info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES: if any error, all DMA channels will be masked.
|
|||
|
// if no error, all DMA channels will be masked except
|
|||
|
// for channel 4 which is used to cascade the two DMA
|
|||
|
// controllers.
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaMaskTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
UCHAR DmaIndex; // DMA channel within controller
|
|||
|
ULONG DmaCtrl = 0; // DMA controller
|
|||
|
PUCHAR Clear, MaskAll, Mask, MaskStatus; // port address
|
|||
|
BOOLEAN CheckOk = TRUE; // check status
|
|||
|
|
|||
|
PRINTDBG("EisaDmaMaskTest\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// one loop per DMA controller
|
|||
|
//
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
//
|
|||
|
// initialize port values
|
|||
|
//
|
|||
|
|
|||
|
Clear = EisaIoStart + EisaDmaCtrlTest[ DmaCtrl ].Clear;
|
|||
|
MaskAll = EisaIoStart + EisaDmaCtrlTest[ DmaCtrl ].MaskAll;
|
|||
|
Mask = EisaIoStart + EisaDmaCtrlTest[ DmaCtrl ].Mask;
|
|||
|
MaskStatus = EisaIoStart + EisaDmaCtrlTest[ DmaCtrl ].MaskStatus;
|
|||
|
|
|||
|
//
|
|||
|
// test mask clear register
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Clear, 0x00 );
|
|||
|
if ( EisaInUchar( MaskStatus ) & 0xF )
|
|||
|
{
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// now set all the mask bits
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( MaskAll, 0x0F );
|
|||
|
if ( (EisaInUchar( MaskStatus ) & 0x0F) != 0x0F )
|
|||
|
{
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// now test each single mask bit
|
|||
|
//
|
|||
|
|
|||
|
for ( DmaIndex=0; DmaIndex < 4; DmaIndex++ )
|
|||
|
{
|
|||
|
//
|
|||
|
// clear single bit
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Mask, DmaIndex );
|
|||
|
if ( EisaInUchar( MaskStatus ) & (1 << DmaIndex))
|
|||
|
{
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// set single bit
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Mask, 0x04 | DmaIndex );
|
|||
|
if ( !(EisaInUchar( MaskStatus ) & (1 << DmaIndex)))
|
|||
|
{
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
while( CheckOk && !DmaCtrl++ );
|
|||
|
|
|||
|
//
|
|||
|
// return check status
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + DMA_MASKS03, 0x0F );
|
|||
|
EisaOutUchar( EisaIoStart + DMA_MASKS47, CheckOk ? 0x0E : 0x0F );
|
|||
|
|
|||
|
return CheckOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDmaPageTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests the low and high pages.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pDmaInfo DMA info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES: The low and high page registers will be left in
|
|||
|
// the power-on state of 0x00.
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaPageTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
ULONG DmaChannel; // # of DMA channel
|
|||
|
PUCHAR Port1, Port2; // general I/O ports
|
|||
|
BOOLEAN CheckOk = TRUE; // check status
|
|||
|
|
|||
|
PRINTDBG("EisaDmaPageTest\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// one loop per DMA channel
|
|||
|
//
|
|||
|
|
|||
|
for ( DmaChannel = 0; DmaChannel < EISA_DMAS; DmaChannel++ )
|
|||
|
{
|
|||
|
|
|||
|
Port1 = EisaIoStart + EisaDmaRegsTest[ DmaChannel ].LowPage;
|
|||
|
Port2 = EisaIoStart + EisaDmaRegsTest[ DmaChannel ].HighPage;
|
|||
|
|
|||
|
//
|
|||
|
// check high page address
|
|||
|
//
|
|||
|
|
|||
|
if ( DmaChannel != 4 )
|
|||
|
{
|
|||
|
EisaOutUchar( Port2, 0xFF );
|
|||
|
|
|||
|
if ( !EisaCheckReg( Port2, 0xFF ) )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check low page register
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port1, 0x00 );
|
|||
|
|
|||
|
if ( !EisaCheckReg( Port1, 0xFF ) )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check if high reg has been cleared writing to low reg
|
|||
|
//
|
|||
|
|
|||
|
if ( DmaChannel != 4 && EisaInUchar( Port2 ) != 0 )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// return check status
|
|||
|
//
|
|||
|
|
|||
|
return CheckOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDmaAddressTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests the address register.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pDmaInfo DMA info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES: The address registers will be left in the power-on
|
|||
|
// state of 0x0000.
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaAddressTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
ULONG DmaChannel; // # of DMA channel
|
|||
|
PUCHAR Port1, Port2; // general I/O ports
|
|||
|
BOOLEAN CheckOk = TRUE; // check status
|
|||
|
|
|||
|
PRINTDBG("EisaDmaAddressTest\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// reset the internal DMA pointers
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + DMA_FF_CLR03, 0x00 );
|
|||
|
EisaOutUchar( EisaIoStart + DMA_FF_CLR47, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// one loop per DMA channel
|
|||
|
//
|
|||
|
|
|||
|
for ( DmaChannel = 0; DmaChannel < EISA_DMAS; DmaChannel++ )
|
|||
|
{
|
|||
|
//
|
|||
|
// load high and address register addresses
|
|||
|
//
|
|||
|
|
|||
|
Port1 = EisaIoStart + EisaDmaRegsTest[ DmaChannel ].Address;
|
|||
|
Port2 = EisaIoStart + EisaDmaRegsTest[ DmaChannel ].HighPage;
|
|||
|
|
|||
|
//
|
|||
|
// write a value different from zero in high page
|
|||
|
//
|
|||
|
|
|||
|
if ( DmaChannel != 4 )
|
|||
|
{
|
|||
|
EisaOutUchar( Port2, 0xFF );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check word register using one 8 bit port
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaCheckDeepReg( Port1 ) )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// initialize register
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port1, 0x00 );
|
|||
|
EisaOutUchar( Port1, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// check if high reg has been cleared writing to low reg
|
|||
|
//
|
|||
|
|
|||
|
if ( DmaChannel != 4 && EisaInUchar( Port2 ) != 0 )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// return check status
|
|||
|
//
|
|||
|
|
|||
|
return CheckOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDmaCountTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests the count register.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pDmaInfo DMA info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES: The count registers will be left in the power-on
|
|||
|
// state of 0x00 (high) and 0xFFFF (low).
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaCountTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
ULONG DmaChannel; // # of DMA channel
|
|||
|
PUCHAR Port1, Port2; // general I/O ports
|
|||
|
BOOLEAN CheckOk = TRUE; // check status
|
|||
|
|
|||
|
PRINTDBG("EisaDmaCountTest\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// reset the internal DMA pointers
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + DMA_FF_CLR03, 0x00 );
|
|||
|
EisaOutUchar( EisaIoStart + DMA_FF_CLR47, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// one loop per DMA channel
|
|||
|
//
|
|||
|
|
|||
|
for ( DmaChannel = 0; DmaChannel < EISA_DMAS; DmaChannel++ )
|
|||
|
{
|
|||
|
//
|
|||
|
// load high and address register addresses
|
|||
|
//
|
|||
|
|
|||
|
Port1 = EisaIoStart + EisaDmaRegsTest[ DmaChannel ].LowCount;
|
|||
|
Port2 = EisaIoStart + EisaDmaRegsTest[ DmaChannel ].HighCount;
|
|||
|
|
|||
|
//
|
|||
|
// check high count register
|
|||
|
//
|
|||
|
|
|||
|
if ( DmaChannel != 4 )
|
|||
|
{
|
|||
|
EisaOutUchar( Port2, 0xFF );
|
|||
|
|
|||
|
if ( !EisaCheckReg( Port2, 0xFF ) )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check word register using one 8 bit port
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaCheckDeepReg( Port1 ) )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// initialize register
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port1, 0xFF );
|
|||
|
EisaOutUchar( Port1, 0xFF );
|
|||
|
|
|||
|
//
|
|||
|
// check if high reg has been cleared writing to low reg
|
|||
|
//
|
|||
|
|
|||
|
if ( DmaChannel != 4 && EisaInUchar( Port2 ) != 0 )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// return check status
|
|||
|
//
|
|||
|
|
|||
|
return CheckOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDmaStopTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests the stop register.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pDmaInfo DMA info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES: The count registers will be left in the power-on
|
|||
|
// state of 0xFFFFFC.
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaDmaStopTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
ULONG DmaChannel; // # of DMA channel
|
|||
|
PUCHAR Stop; // general I/O ports
|
|||
|
BOOLEAN CheckOk = TRUE; // check status
|
|||
|
|
|||
|
PRINTDBG("EisaDmaStopTest\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// one loop per DMA channel
|
|||
|
//
|
|||
|
|
|||
|
for ( DmaChannel = 0; DmaChannel < EISA_DMAS; DmaChannel++ )
|
|||
|
{
|
|||
|
|
|||
|
Stop = EisaIoStart + EisaDmaRegsTest[ DmaChannel ].Stop;
|
|||
|
|
|||
|
//
|
|||
|
// check high page address
|
|||
|
//
|
|||
|
|
|||
|
if ( DmaChannel != 4 )
|
|||
|
{
|
|||
|
//
|
|||
|
// initialize stop registers and test them
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Stop, 0x00 );
|
|||
|
EisaOutUchar( Stop+1, 0x00 );
|
|||
|
EisaOutUchar( Stop+2, 0x00 );
|
|||
|
|
|||
|
if ( !EisaCheckReg( Stop, 0xFC ) ||
|
|||
|
!EisaCheckReg( Stop+1, 0xFF ) ||
|
|||
|
!EisaCheckReg( Stop+2, 0xFF ) )
|
|||
|
{
|
|||
|
//
|
|||
|
// error
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// return check status
|
|||
|
//
|
|||
|
|
|||
|
return CheckOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDmaIni:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function initializes the DMA controllers of
|
|||
|
// the specified EISA bus.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pDmaInfo DMA info pointer
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaDmaIni
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_DMA_INFO pDmaInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
ULONG Index; // general index
|
|||
|
ULONG DmaCtrl = 0; // DMA controller
|
|||
|
UCHAR Reg = 0; // DMA command Register
|
|||
|
PUCHAR Port; // general port
|
|||
|
|
|||
|
PRINTDBG("EisaDmaIni\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//-----------------------------------------------------------------
|
|||
|
//
|
|||
|
// set command registers for fixed priotiry, DREQ active high,
|
|||
|
// DACK# active low and channels enabled
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + DMA_COMMAND03, Reg );
|
|||
|
EisaOutUchar( EisaIoStart + DMA_COMMAND47, Reg );
|
|||
|
|
|||
|
//-----------------------------------------------------------------
|
|||
|
//
|
|||
|
// initialize mode register for channel 4. The other channels will
|
|||
|
// be initializated during the EisaRequestDmaTransfer functions.
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + DMA_MODE47, 0xC0 );
|
|||
|
|
|||
|
//-----------------------------------------------------------------
|
|||
|
//
|
|||
|
// disable the chaining mode
|
|||
|
//
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
//
|
|||
|
// load the controller port address
|
|||
|
//
|
|||
|
|
|||
|
Port = EisaIoStart + EisaDmaCtrlTest[ DmaCtrl ].Chain;
|
|||
|
|
|||
|
//
|
|||
|
// disable chaining mode
|
|||
|
//
|
|||
|
|
|||
|
for ( Index = 0; Index < 4 ; Index++ )
|
|||
|
{
|
|||
|
EisaOutUchar( Port, 0x00 );
|
|||
|
}
|
|||
|
}
|
|||
|
while( !DmaCtrl++ );
|
|||
|
|
|||
|
//-----------------------------------------------------------------
|
|||
|
//
|
|||
|
// initialize DMA structures
|
|||
|
//
|
|||
|
|
|||
|
for ( Index = 0; Index < EISA_DMAS; Index++ )
|
|||
|
{
|
|||
|
pDmaInfo->DmaFlags[ Index ].Busy = 0;
|
|||
|
pDmaInfo->DmaFlags[ Index ].Tc = 0;
|
|||
|
|
|||
|
// stop enabled, T-C output, ISA compatible,
|
|||
|
// 8 bit I/O byte count and DMA channel
|
|||
|
// (see DMA configuration).
|
|||
|
|
|||
|
pDmaInfo->DmaExtReg[ Index ] = Index < 4 ? Index : Index - 4;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// all done
|
|||
|
//
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaOtherPod:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests and initializes all the general
|
|||
|
// ports of the EISA bus.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pPortInfo port info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaOtherPod
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN ChkOk;
|
|||
|
|
|||
|
PRINTDBG("EisaOtherPod\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// if ini already done, return status
|
|||
|
//
|
|||
|
|
|||
|
if ( pPortInfo->Flags.IniDone )
|
|||
|
{
|
|||
|
return (BOOLEAN)(pPortInfo->Flags.Error);
|
|||
|
}
|
|||
|
pPortInfo->Flags.Error = 0;
|
|||
|
|
|||
|
//
|
|||
|
// check and initialize NMI
|
|||
|
//
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
EisaCheckpointFirstFase( EisaNmi );
|
|||
|
if ( !( ChkOk = EisaNmiTest( EisaIoStart, pPortInfo )))
|
|||
|
{
|
|||
|
pPortInfo->Flags.Error = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
while ( EisaCheckpointFinalFase( EisaNmi, ChkOk ));
|
|||
|
|
|||
|
//
|
|||
|
// check and initialize refresh
|
|||
|
//
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
EisaCheckpointFirstFase( EisaRefresh );
|
|||
|
if ( !( ChkOk = EisaRefreshTest( EisaIoStart, pPortInfo )))
|
|||
|
{
|
|||
|
pPortInfo->Flags.Error = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
while ( EisaCheckpointFinalFase( EisaRefresh, ChkOk ));
|
|||
|
|
|||
|
//
|
|||
|
// check and initialize port 61
|
|||
|
//
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
EisaCheckpointFirstFase( EisaPort61 );
|
|||
|
if ( !( ChkOk = EisaPort61Test( EisaIoStart, pPortInfo )))
|
|||
|
{
|
|||
|
pPortInfo->Flags.Error = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
while ( EisaCheckpointFinalFase( EisaPort61, ChkOk ));
|
|||
|
|
|||
|
//
|
|||
|
// check and initialize timer1
|
|||
|
//
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
EisaCheckpointFirstFase( EisaTimer1 );
|
|||
|
if ( !( ChkOk = EisaTimer1Test( EisaIoStart, pPortInfo )))
|
|||
|
{
|
|||
|
pPortInfo->Flags.Error = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
while ( EisaCheckpointFinalFase( EisaTimer1, ChkOk ));
|
|||
|
|
|||
|
//
|
|||
|
// check and initialize timer2
|
|||
|
//
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
EisaCheckpointFirstFase( EisaTimer2 );
|
|||
|
if ( !( ChkOk = EisaTimer2Test( EisaIoStart, pPortInfo )))
|
|||
|
{
|
|||
|
pPortInfo->Flags.Error = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
while ( EisaCheckpointFinalFase( EisaTimer2, ChkOk ));
|
|||
|
|
|||
|
//
|
|||
|
// return check status
|
|||
|
//
|
|||
|
|
|||
|
pPortInfo->Flags.IniDone = 1;
|
|||
|
return !(BOOLEAN)(pPortInfo->Flags.Error);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaNmiTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests and initializes the EISA NMI.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pPortInfo port info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS: EisaNmiFlag
|
|||
|
//
|
|||
|
// NOTES: if any error, the NMI will be disabled (real-time clock)
|
|||
|
// if no error, the NMI will be left enabled but with all
|
|||
|
// the NMI sources disabled.
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaNmiTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaNmiTest\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
// NOTE: NMI test is disabled for JAZZ.
|
|||
|
#if 0
|
|||
|
//
|
|||
|
// install an NMI interrupt handler
|
|||
|
//
|
|||
|
|
|||
|
EisaNmiFlag = FALSE;
|
|||
|
|
|||
|
FwInstallIntVector( EISA_NMI_VECTOR, EisaNmiHandlerTest );
|
|||
|
|
|||
|
//----------------------------------------------------------------
|
|||
|
//
|
|||
|
// disable all the NMI sources
|
|||
|
// (using the extended NMI status and contrl port and system control port B)
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + EISA_SYS_EXT_NMI, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// note that the following operation clears any pending parity or I/O check
|
|||
|
// errors.
|
|||
|
//
|
|||
|
|
|||
|
EisaDisableParityIoCheck( EisaIoStart );
|
|||
|
EisaEnableNmi( EisaIoStart );
|
|||
|
|
|||
|
//
|
|||
|
// ... wait.
|
|||
|
//
|
|||
|
|
|||
|
ArcEisaStallProcessor( EISA_WAIT_NMI_TEST );
|
|||
|
EisaDisableNmi( EisaIoStart );
|
|||
|
|
|||
|
//
|
|||
|
// return error if an hot EISA NMI
|
|||
|
//
|
|||
|
|
|||
|
if ( EisaNmiFlag )
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------
|
|||
|
//
|
|||
|
// enable all the NMI sources used by the fw
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + EISA_SYS_EXT_NMI, EISA_ENABLE_NMI_32 );
|
|||
|
EisaEnableParityIoCheck( EisaIoStart );
|
|||
|
EisaEnableNmi( EisaIoStart );
|
|||
|
|
|||
|
//
|
|||
|
// ... wait
|
|||
|
//
|
|||
|
|
|||
|
ArcEisaStallProcessor( EISA_WAIT_NMI_TEST );
|
|||
|
EisaDisableNmi( EisaIoStart );
|
|||
|
|
|||
|
//
|
|||
|
// return error if an hot EISA NMI
|
|||
|
//
|
|||
|
|
|||
|
if ( EisaNmiFlag )
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------
|
|||
|
//
|
|||
|
// enable NMI I/O port and NMI; and force one to come
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + EISA_SYS_EXT_NMI, EISA_ENABLE_NMI_IO );
|
|||
|
EisaEnableNmi( EisaIoStart );
|
|||
|
EisaOutUchar( EisaIoStart + EISA_SW_NMI_PORT, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// ... wait
|
|||
|
//
|
|||
|
|
|||
|
ArcEisaStallProcessor( EISA_WAIT_NMI_TEST );
|
|||
|
EisaDisableNmi( EisaIoStart );
|
|||
|
|
|||
|
//
|
|||
|
// return an error if not NMI
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaNmiFlag )
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// enable the NMI and all the NMI sources used by fw
|
|||
|
// ( the software NMI will be disabled )
|
|||
|
//
|
|||
|
|
|||
|
FwInstallIntVector( EISA_NMI_VECTOR, EisaNmiHandler );
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + EISA_SYS_EXT_NMI, EISA_ENABLE_NMI_32 );
|
|||
|
EisaEnableNmi( EisaIoStart );
|
|||
|
|
|||
|
//
|
|||
|
// return
|
|||
|
//
|
|||
|
|
|||
|
#endif // 0
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaNmiHandlerTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function is the NMI handler during the NMI test.
|
|||
|
//
|
|||
|
// ARGUMENTS: Cause R4000 cause register
|
|||
|
//
|
|||
|
// RETURN: TRUE interrupt recognized
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS: EisaNmi
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaNmiHandlerTest
|
|||
|
(
|
|||
|
IN ULONG Couse
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaNmiHandlerTest\n\r"); // DEBUG SUPPORT
|
|||
|
StatusReg( ~STATUS_EISA_NMI, (ULONG)0 );
|
|||
|
EisaNmiFlag = TRUE;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaNmiHandler:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function handles the EISA NMI.
|
|||
|
// An NMI can be caused by :
|
|||
|
//
|
|||
|
// 1) System/Adapter board memory parity error
|
|||
|
// ( port 61h bit 7 set )
|
|||
|
// 2) Adapter I/O channel check error
|
|||
|
// ( port 61h bit 6 set )
|
|||
|
// 3) Fail-Safe Timer (channle 2 or the interval Timer 2)
|
|||
|
// ( port 461h bit 7 set ) - NOT CHECKED *
|
|||
|
// 4) DMA bus timeout error
|
|||
|
// ( port 461h bit 6 set )
|
|||
|
// 5) Write to NMI port 462h
|
|||
|
// ( port 461h bit 5 set ) - NOT CHECKED *
|
|||
|
// 6) Coprocessor exception interrupt - NOT CHECKED *
|
|||
|
//
|
|||
|
// An error message will be displayed indicating the
|
|||
|
// cause of the error and the system will halt.
|
|||
|
// The only allowed operation after an NMI is to reset
|
|||
|
// the machine.
|
|||
|
//
|
|||
|
// * The firmware doesn't enable these NMI sources.
|
|||
|
//
|
|||
|
// ARGUMENTS: Cause R4000 cause register
|
|||
|
//
|
|||
|
// RETURN: TRUE interrupt recognized
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS: EisaBusInfo
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaNmiHandler
|
|||
|
(
|
|||
|
IN ULONG Couse
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
PUCHAR EisaIoStart; // eisa I/O virtual address
|
|||
|
UCHAR NmiData, ExtNmiData; // NMI status
|
|||
|
ULONG BusNumber = 0; // eisa bus number
|
|||
|
ULONG Slots; // # slots
|
|||
|
BOOLEAN NmiPresent; // NMI source status
|
|||
|
|
|||
|
PRINTDBG("EisaNmiHandler\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// disable NMI at CPU level
|
|||
|
//
|
|||
|
|
|||
|
StatusReg( ~STATUS_EISA_NMI, (ULONG)0 );
|
|||
|
|
|||
|
//
|
|||
|
// clear screen and display message
|
|||
|
//
|
|||
|
|
|||
|
FwClearScreen();
|
|||
|
FwPrint(EISA_HOT_NMI_MSG);
|
|||
|
EisaCheckpointFirstFase( EisaHotNmi );
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
//
|
|||
|
// print eisa bus number
|
|||
|
//
|
|||
|
|
|||
|
FwPrint( EISA_BUS_NUMBER_MSG , BusNumber );
|
|||
|
|
|||
|
//
|
|||
|
// initialize variables
|
|||
|
//
|
|||
|
|
|||
|
EisaIoStart = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
|
|||
|
Slots = EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots;
|
|||
|
NmiPresent = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// read NMI status
|
|||
|
//
|
|||
|
|
|||
|
NmiData = EisaInUchar( EisaIoStart + EISA_SYS_CTRL_PORTB );
|
|||
|
ExtNmiData = EisaInUchar( EisaIoStart + EISA_SYS_EXT_NMI );
|
|||
|
|
|||
|
//
|
|||
|
// check if there is a parity error
|
|||
|
//
|
|||
|
|
|||
|
if ( NmiData & EISA_PARITY_STATUS )
|
|||
|
{
|
|||
|
EisaParityError( EisaIoStart );
|
|||
|
NmiPresent = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check if there is a I/O channel check
|
|||
|
//
|
|||
|
|
|||
|
if ( NmiData & EISA_IOCHK_STATUS )
|
|||
|
{
|
|||
|
EisaIoChkError( EisaIoStart, Slots );
|
|||
|
NmiPresent = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check if there is a DMA or bus master timeout error
|
|||
|
//
|
|||
|
|
|||
|
if ( ExtNmiData & EISA_NMI_32_STATUS )
|
|||
|
{
|
|||
|
if ( ExtNmiData & EISA_NMI_32_CAUSE )
|
|||
|
{
|
|||
|
EisaBusTimeoutError( EisaIoStart, Slots );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
EisaSlaveTimeoutError( EisaIoStart, Slots );
|
|||
|
}
|
|||
|
NmiPresent = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// if no NMI for this bus, display "no problem"
|
|||
|
//
|
|||
|
|
|||
|
if ( !NmiPresent )
|
|||
|
{
|
|||
|
FwPrint(EISA_NMI_NOT_FOUND_MSG);
|
|||
|
}
|
|||
|
}
|
|||
|
while( ++BusNumber < EISA_BUSES );
|
|||
|
|
|||
|
//
|
|||
|
// print final message and hang
|
|||
|
//
|
|||
|
|
|||
|
EisaCheckpointFinalFase( EisaHotNmi, FALSE );
|
|||
|
while(1); // just to be sure
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaParityError:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function displays the error message and
|
|||
|
// returns to the caller without do any other thing.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaParityError
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaParityError\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
FwPrint(EISA_PARITY_ERROR_MSG , ASCII_CSI );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaIoChkError:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tries to find the slot in error.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// Slots # slots
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaIoChkError
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN ULONG Slots
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variabls
|
|||
|
//
|
|||
|
|
|||
|
ULONG AdapId; // adapter ID
|
|||
|
PUCHAR ExpCtrl; // expansion board ctrl addr
|
|||
|
UCHAR CtrlBits; // port value
|
|||
|
|
|||
|
PRINTDBG("EisaIoChkError\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// display first message
|
|||
|
//
|
|||
|
|
|||
|
FwPrint(EISA_IO_CHECK_ERROR_MSG , ASCII_CSI);
|
|||
|
|
|||
|
//
|
|||
|
// check all slots starting from the last one
|
|||
|
//
|
|||
|
|
|||
|
while( --Slots )
|
|||
|
{
|
|||
|
//
|
|||
|
// check if there is an adapter with a readable ID
|
|||
|
//
|
|||
|
|
|||
|
if ( !EisaReadReadyId( EisaIoStart, Slots, &AdapId ) ||
|
|||
|
AdapId == NO_ADAP_ID )
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
ExpCtrl = EisaIoStart + 0x1000 * Slots + EXPANSION_BOARD_CTRL_BITS;
|
|||
|
|
|||
|
//
|
|||
|
// test the IOCHKERR bit of the Expansion Board Contrl Bits.
|
|||
|
// the IOCHKERR bit can be read to determine if an expansion
|
|||
|
// board has a pending error. The expansion board indicates a
|
|||
|
// pending error by setting IOCHKERR, clearing the ENABLE bit
|
|||
|
// and entering the disabled state.
|
|||
|
//
|
|||
|
// note: because the EISA expansion boards are not required to
|
|||
|
// support this port, we need the following simple
|
|||
|
// assumption: this I/O port is not supported if the value
|
|||
|
// read from it is 0xFF.
|
|||
|
//
|
|||
|
|
|||
|
if ((CtrlBits = EisaInUchar( ExpCtrl )) != 0xFF )
|
|||
|
{
|
|||
|
if ( CtrlBits & EISA_IOCHKERR )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// print final message
|
|||
|
//
|
|||
|
|
|||
|
if ( !Slots )
|
|||
|
{
|
|||
|
FwPrint( EISA_IO_CHECK_NOT_SUP_MSG ); // slot not found
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
FwPrint(EISA_IN_SLOT_MSG , Slots ); // slot in error
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// all done, exit
|
|||
|
//
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaBusTimeoutError:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function displays the bus master number in error.
|
|||
|
// If a 32-bit bus master tries to hold the bus beyond
|
|||
|
// the BUS limit (8 usec if BCLK = 8 MHz), the ISP will
|
|||
|
// assert the NMI and RSTDRV signals togheter.
|
|||
|
// The RSTDRV signal will remain aserted until the NMI has
|
|||
|
// been reset by plsing bit 3 of I/O port 461h.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// Slots # slots
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaBusTimeoutError
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN ULONG Slots
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
UCHAR Status; // 32-bit bus master status
|
|||
|
ULONG BusMaster = 0; // bus master number in error
|
|||
|
PUCHAR ExtNmi; // extended NMI control
|
|||
|
|
|||
|
PRINTDBG("EisaBusTimeoutError\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// find the bus master group in error
|
|||
|
//
|
|||
|
|
|||
|
if ( ~(Status = EisaInUchar(EisaIoStart+EISA_BUSMASTER_LSTATUS)) & 0xFF )
|
|||
|
{
|
|||
|
BusMaster = 1;
|
|||
|
}
|
|||
|
else if ( ~(Status = (EisaInUchar(EisaIoStart+EISA_BUSMASTER_HSTATUS) |
|
|||
|
0x80)) & 0xFF )
|
|||
|
{
|
|||
|
BusMaster = 9;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// find the bus master number in error and display it
|
|||
|
//
|
|||
|
|
|||
|
FwPrint( EISA_BUS_MASTER_MSG, ASCII_CSI );
|
|||
|
|
|||
|
if ( BusMaster )
|
|||
|
{
|
|||
|
for (; Status & 1; Status >>= 1, BusMaster++ );
|
|||
|
FwPrint(EISA_TIMEOUT_MSG , BusMaster );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
FwPrint(EISA_TIMEOUT2_MSG ); // bus master not found
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// reset NMI
|
|||
|
//
|
|||
|
|
|||
|
ExtNmi = EisaIoStart + EISA_SYS_EXT_NMI;
|
|||
|
EisaOutUchar( ExtNmi, EisaInUchar( ExtNmi ) & ~EISA_ENABLE_NMI_32 );
|
|||
|
|
|||
|
//
|
|||
|
// all done
|
|||
|
//
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaSlaveTimeoutError:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function displays an error message.
|
|||
|
// If a memory slave extends a cycle long enough that
|
|||
|
// CMD# is active for more than 256 BCLKs (32usec if
|
|||
|
// BCLK = 8MHz), the ISP will assert the NMI and RSTDRV
|
|||
|
// signals togheter.
|
|||
|
// The RSTDRV signal will remain aserted until the NMI has
|
|||
|
// been reset by plsing bit 3 of I/O port 461h.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// Slots # slots
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaSlaveTimeoutError
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN ULONG Slots
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
PUCHAR ExtNmi; // extended NMI control
|
|||
|
|
|||
|
PRINTDBG("EisaSlaveTimeoutError\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// display the error message
|
|||
|
//
|
|||
|
|
|||
|
FwPrint(EISA_SLAVE_TIMEOUT_MSG , ASCII_CSI );
|
|||
|
|
|||
|
//
|
|||
|
// reset NMI
|
|||
|
//
|
|||
|
|
|||
|
ExtNmi = EisaIoStart + EISA_SYS_EXT_NMI;
|
|||
|
EisaOutUchar( ExtNmi, EisaInUchar( ExtNmi ) & ~EISA_ENABLE_NMI_32 );
|
|||
|
|
|||
|
//
|
|||
|
// all done
|
|||
|
//
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaRefreshTest:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests and initializes the EISA refresh.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pPortInfo port info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES: the refresh will be left enabled.
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaRefreshTest
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN CheckOk = FALSE; // checking status
|
|||
|
ULONG Retry; // # retry
|
|||
|
PUCHAR Port; // general I/O port
|
|||
|
|
|||
|
PRINTDBG("EisaRefreshTest\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// clear refresh pages
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + DMA_PAGE_RFR, 0x00 );
|
|||
|
EisaOutUchar( EisaIoStart + DMA_HPAGE_RFR, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// start timer 1, counter 1
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + EISA_TIMER1_CTRL, 0x54 );
|
|||
|
EisaOutUchar( EisaIoStart + EISA_TIMER1_COUNTER1, EISA_RFR_COUNT );
|
|||
|
|
|||
|
//
|
|||
|
// check if refresh bit in the system control port B is toggling
|
|||
|
//
|
|||
|
|
|||
|
Port = EisaIoStart + EISA_SYS_CTRL_PORTB;
|
|||
|
|
|||
|
for ( CheckOk = FALSE, Retry = EISA_RFR_RETRY; Retry; Retry-- )
|
|||
|
{
|
|||
|
//
|
|||
|
// check if refresh bit is set
|
|||
|
//
|
|||
|
|
|||
|
if ( READ_REGISTER_UCHAR( Port ) & EISA_REFRESH )
|
|||
|
{
|
|||
|
//
|
|||
|
// yes, exit loop
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = TRUE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// if time-out, exit with error
|
|||
|
//
|
|||
|
|
|||
|
if ( !Retry )
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check if refresh bit in the system control port B is toggling
|
|||
|
//
|
|||
|
|
|||
|
for ( CheckOk = FALSE, Retry = EISA_RFR_RETRY; Retry; Retry-- )
|
|||
|
{
|
|||
|
//
|
|||
|
// check if refresh bit is cleared
|
|||
|
//
|
|||
|
|
|||
|
if ( !(READ_REGISTER_UCHAR( Port ) & EISA_REFRESH) )
|
|||
|
{
|
|||
|
//
|
|||
|
// yes, exit loop
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = TRUE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// return check status
|
|||
|
//
|
|||
|
|
|||
|
return CheckOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaPort61Test:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests and initializes the system
|
|||
|
// control port B.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pPortInfo port info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS: NMI has already been tested.
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES: The parity and the I/O channel check, The speaker gate
|
|||
|
// and speaker timer will be left disabled.
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaPort61Test
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
PUCHAR Port; // genearl I/O port
|
|||
|
BOOLEAN CheckOk = TRUE; // check status
|
|||
|
|
|||
|
PRINTDBG("EisaPort61Test\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
Port = EisaIoStart + EISA_SYS_CTRL_PORTB;
|
|||
|
|
|||
|
//
|
|||
|
// gate signal for speaker timer
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port, EISA_SPEAKER_GATE );
|
|||
|
if ( (EisaInUchar( Port ) & 0x0F) != EISA_SPEAKER_GATE )
|
|||
|
{
|
|||
|
CheckOk = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// speaker timer contrl
|
|||
|
//
|
|||
|
|
|||
|
if ( CheckOk )
|
|||
|
{
|
|||
|
EisaOutUchar( Port, EISA_SPEAKER_TIMER);
|
|||
|
if ( (EisaInUchar( Port ) & 0x0F) != EISA_SPEAKER_TIMER )
|
|||
|
{
|
|||
|
CheckOk = FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// parity bit
|
|||
|
//
|
|||
|
|
|||
|
if ( CheckOk )
|
|||
|
{
|
|||
|
EisaOutUchar( Port, EISA_PARITY_OFF);
|
|||
|
if ( (EisaInUchar( Port ) & 0x0F) != EISA_PARITY_OFF )
|
|||
|
{
|
|||
|
CheckOk = FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// I/O channel check
|
|||
|
//
|
|||
|
|
|||
|
if ( CheckOk )
|
|||
|
{
|
|||
|
EisaOutUchar( Port, EISA_IOCHK_OFF );
|
|||
|
if ( (EisaInUchar( Port ) & 0x0F) != EISA_IOCHK_OFF )
|
|||
|
{
|
|||
|
CheckOk = FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// initialize port 61h.
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// return check status
|
|||
|
//
|
|||
|
|
|||
|
return CheckOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaTimer1Test:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function tests only the counter 2 of
|
|||
|
// timer 1 (speaker).
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pPortInfo port info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
// FALSE Error
|
|||
|
//
|
|||
|
// ASSUMPTIONS: NMI has already been tested.
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES: The functions stops timer1 counter0, turns off the
|
|||
|
// timer1 counter2 gate and disable the speaker output.
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaTimer1Test
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN CheckOk = FALSE; // check status
|
|||
|
PUCHAR Ctrl, Port, Port61; // genearl I/O ports
|
|||
|
|
|||
|
PRINTDBG("EisaTimer1Test\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// initialize variables
|
|||
|
//
|
|||
|
|
|||
|
Ctrl = EisaIoStart + EISA_TIMER1_CTRL;
|
|||
|
Port = EisaIoStart + EISA_TIMER1_COUNTER2;
|
|||
|
Port61 = EisaIoStart + EISA_SYS_CTRL_PORTB;
|
|||
|
|
|||
|
//
|
|||
|
// disable timer1 counter2 gate, speaker output
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port61, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// program timer 1, counter 2 (speaker) in 16-bit count, mode 0
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Ctrl, 0xB0 );
|
|||
|
EisaOutUchar( Port, 0x00 );
|
|||
|
EisaOutUchar( Port, 0x80 );
|
|||
|
|
|||
|
//
|
|||
|
// check register
|
|||
|
//
|
|||
|
|
|||
|
if ( !(EisaCheckDeepReg( Port )));
|
|||
|
|
|||
|
//
|
|||
|
// check speaker output. It must be low otherwise there is an error
|
|||
|
//
|
|||
|
|
|||
|
else if ( EisaInUchar( Port61 ) & EISA_SPEAKER_OUT );
|
|||
|
|
|||
|
//
|
|||
|
// enable speaker gate to enable the counter, wait for some time and
|
|||
|
// check if speaker output is high, if not error out
|
|||
|
//
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// enable speaker gate
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port61, EISA_SPEAKER_GATE );
|
|||
|
|
|||
|
//
|
|||
|
// wait 40msec = ~ ( 0x8000 / 1.193 Mhz ) + something
|
|||
|
//
|
|||
|
|
|||
|
// NOTE: Wait longer for JAZZ.
|
|||
|
// ArcEisaStallProcessor( 40 * 1000 );
|
|||
|
ArcEisaStallProcessor( 160 * 1000 );
|
|||
|
|
|||
|
//
|
|||
|
// check speaker output
|
|||
|
//
|
|||
|
|
|||
|
if ( EisaInUchar( Port61 ) & EISA_SPEAKER_OUT )
|
|||
|
{
|
|||
|
//
|
|||
|
// initialize timer1 counter2 in 16-bit , mode 3
|
|||
|
//
|
|||
|
|
|||
|
// EisaOutUchar( Ctrl, 0xB6 );
|
|||
|
// EisaOutUchar( Port,
|
|||
|
// (UCHAR)( EISA_SPEAKER_CLOCK/EISA_SPEAKER_FREQ ));
|
|||
|
// EisaOutUchar( Port,
|
|||
|
// (UCHAR)( (EISA_SPEAKER_CLOCK/EISA_SPEAKER_FREQ) >> 8 ));
|
|||
|
|
|||
|
//
|
|||
|
// all done
|
|||
|
//
|
|||
|
|
|||
|
CheckOk = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// disable speaker gate, speaker output
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port61, 0x00 );
|
|||
|
|
|||
|
//
|
|||
|
// stop timer1 counter0 sending the control word without the count value
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Ctrl, 0x30 );
|
|||
|
|
|||
|
//
|
|||
|
// all done, exit
|
|||
|
//
|
|||
|
|
|||
|
return CheckOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaTimer2Test:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function stops the timer2 counter0 (Fail-safe).
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pPortInfo port info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE All done
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaTimer2Test
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_PORT_INFO pPortInfo
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaTimer2Test\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// stop timer2 counter0 sending the control word without the count value
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + EISA_TIMER2_CTRL, 0x30 );
|
|||
|
|
|||
|
//
|
|||
|
// all done, exit
|
|||
|
//
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaClearPendingInt:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function cleares the specified pending interrupt.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pIntInfo interrupt info pointer
|
|||
|
// Irq IRQ to reset
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaClearPendingInt
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN PEISA_INT_INFO pIntInfo,
|
|||
|
IN USHORT Irq
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
PUCHAR PicMask1, PicMask2; // I/O port address
|
|||
|
|
|||
|
PRINTDBG("EisaClearPendingInt\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// initialize variables
|
|||
|
//
|
|||
|
|
|||
|
PicMask1 = EisaIoStart + PIC1_MASK;
|
|||
|
PicMask2 = EisaIoStart + PIC2_MASK;
|
|||
|
|
|||
|
//
|
|||
|
// unmask the specified IRQ
|
|||
|
//
|
|||
|
|
|||
|
if ( Irq > IRQ7 )
|
|||
|
{
|
|||
|
EisaOutUchar( PicMask1, (UCHAR)(~(1 << IRQ2)));
|
|||
|
EisaOutUchar( PicMask2, (UCHAR)(~(1 << (Irq % 8))));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
EisaOutUchar( PicMask1, (UCHAR)(~(1 << Irq )));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// acknowledge the interrupt
|
|||
|
//
|
|||
|
|
|||
|
EisaAckInt( pIntInfo );
|
|||
|
|
|||
|
//
|
|||
|
// mask off all the IRQ lines
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( PicMask1, 0xFF );
|
|||
|
EisaOutUchar( PicMask2, 0xFF );
|
|||
|
|
|||
|
//
|
|||
|
// and send a specific EOF
|
|||
|
//
|
|||
|
|
|||
|
EisaSendSpecificEoi( EisaIoStart, Irq );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaIntAck:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function acknowledges the highest priority
|
|||
|
// interrupt.
|
|||
|
//
|
|||
|
// ARGUMENTS: pIntInfo interrupt info pointer (not used)
|
|||
|
//
|
|||
|
// RETURN: Int interrupt acknowledged.
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
UCHAR
|
|||
|
EisaAckInt
|
|||
|
(
|
|||
|
IN PEISA_INT_INFO pIntInfo
|
|||
|
)
|
|||
|
{
|
|||
|
UCHAR Int;
|
|||
|
|
|||
|
PRINTDBG("EisaAckInt\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
Int = READ_REGISTER_UCHAR( EISA_INT_ACK_ADDR );
|
|||
|
EISA_IO_DELAY;
|
|||
|
|
|||
|
return Int;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaSendSpecificEoi:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function sends a specific EOI to the spcified
|
|||
|
// IRQ line.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// Irq IRQ to reset
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaSendSpecificEoi
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN USHORT Irq
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
PUCHAR PicPort1, PicPort2;
|
|||
|
|
|||
|
PRINTDBG("EisaSendSpecificEoi\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// initialize local variables
|
|||
|
//
|
|||
|
|
|||
|
PicPort1 = EisaIoStart + PIC1;
|
|||
|
PicPort2 = EisaIoStart + PIC2;
|
|||
|
|
|||
|
//
|
|||
|
// send a specific EOI
|
|||
|
//
|
|||
|
|
|||
|
if ( Irq > IRQ7 )
|
|||
|
{
|
|||
|
EisaOutUchar( PicPort2, OCW2_SEOI | ( Irq % 8 ));
|
|||
|
EisaOutUchar( PicPort1, OCW2_SEOI | IRQ2 );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
EisaOutUchar( PicPort1, OCW2_SEOI | Irq );
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDisableParityIoCheck:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function disables the partiy and I/O check NMIs.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaDisableParityIoCheck
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaDisableParityIoCheck\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + EISA_SYS_CTRL_PORTB,
|
|||
|
( EisaInUchar( EisaIoStart + EISA_SYS_CTRL_PORTB ) |
|
|||
|
EISA_PARITY_OFF | EISA_IOCHK_OFF ) & 0x0F );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaEnableParityIoCheck:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function enables the partiy and I/O check NMIs.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaEnableParityIoCheck
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaEnableParityIoCheck\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
EisaOutUchar( EisaIoStart + EISA_SYS_CTRL_PORTB,
|
|||
|
( EisaInUchar( EisaIoStart + EISA_SYS_CTRL_PORTB ) &
|
|||
|
~(EISA_PARITY_OFF | EISA_IOCHK_OFF)) & 0x0F );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDisableInt:
|
|||
|
//
|
|||
|
// DESCRIPTION: The function disables the EISA interrupts at CPU
|
|||
|
// level.
|
|||
|
//
|
|||
|
// ARGUMENTS: none
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaDisableInt
|
|||
|
(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaDisableInt\n\r"); // DEBUG SUPPORT
|
|||
|
StatusReg( ~STATUS_EISA, (ULONG)0 );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaDisableNmi:
|
|||
|
//
|
|||
|
// DESCRIPTION: The function disables the NMI using the real-time
|
|||
|
// clock port.
|
|||
|
//
|
|||
|
// ARGUMENTS: none
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaDisableNmi
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaDisableNmi\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// at real-time clock address port
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar(EisaIoStart+EISA_RTC_CTRL, EISA_DISABLE_NMI+RTC_C_REG);
|
|||
|
READ_REGISTER_UCHAR( RTC_VIRTUAL_BASE );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaEnableNmi:
|
|||
|
//
|
|||
|
// DESCRIPTION: The function enables the NMI line.
|
|||
|
// The following ports are used :
|
|||
|
//
|
|||
|
// . real-time clock ctrl port
|
|||
|
// . CPU status register port
|
|||
|
//
|
|||
|
// ARGUMENTS: none
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaEnableNmi
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart
|
|||
|
)
|
|||
|
{
|
|||
|
PRINTDBG("EisaEnableNmi\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// at real-time clock address port
|
|||
|
//
|
|||
|
EisaReadRtc( EisaIoStart, RTC_C_REG );
|
|||
|
|
|||
|
|
|||
|
// NOTE: this code has been removed because of a R4000 CPU bug.
|
|||
|
//
|
|||
|
// //
|
|||
|
// // at interrupt enable register
|
|||
|
// //
|
|||
|
//
|
|||
|
// EisaBeginCriticalSection();
|
|||
|
// WRITE_REGISTER_UCHAR(INT_ENABLE_ADDR, READ_REGISTER_UCHAR(INT_ENABLE_ADDR) | 0x08);
|
|||
|
// EisaEndCriticalSection();
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// at CPU level
|
|||
|
//
|
|||
|
StatusReg( (ULONG)-1, STATUS_EISA_NMI + STATUS_IE );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaCheckReg:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function performs read/write test on an 8 bit
|
|||
|
// I/O port using the following patterns: FFh, AAh, 55h
|
|||
|
// and 00h. The original part value is restored before
|
|||
|
// returning.
|
|||
|
//
|
|||
|
// ARGUMENTS: Port port address
|
|||
|
// DataMask mask for test pattern to compare with
|
|||
|
// data
|
|||
|
//
|
|||
|
// RETURN: TRUE test completed successfully
|
|||
|
// FALSE error
|
|||
|
//
|
|||
|
// ASSUMPTIONS: none
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaCheckReg
|
|||
|
(
|
|||
|
IN PUCHAR Port,
|
|||
|
IN UCHAR DataMask
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN CompOk = TRUE;
|
|||
|
UCHAR Save, Program;
|
|||
|
|
|||
|
PRINTDBG("EisaCheckReg\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// save original value
|
|||
|
//
|
|||
|
|
|||
|
Save = EisaInUchar( Port );
|
|||
|
|
|||
|
//
|
|||
|
// one loop per each value
|
|||
|
//
|
|||
|
|
|||
|
for ( Program = 0; ; Program += 0x55 )
|
|||
|
{
|
|||
|
//
|
|||
|
// write port, read it back and compare values
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port, Program );
|
|||
|
|
|||
|
if ((EisaInUchar( Port ) & DataMask) != (Program & DataMask))
|
|||
|
{
|
|||
|
//
|
|||
|
// error, value are not the same
|
|||
|
//
|
|||
|
|
|||
|
CompOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// exit loop if last value
|
|||
|
//
|
|||
|
|
|||
|
if ( Program == 0xFF )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// restore original value before returning
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port, Save );
|
|||
|
|
|||
|
return CompOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaCheckDeepReg:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function checks the 2x8bit registers.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// pDmaInfo DMA info pointer
|
|||
|
//
|
|||
|
// RETURN: TRUE check completed successfully
|
|||
|
// FALSE error
|
|||
|
//
|
|||
|
// ASSUMPTIONS: The internal pointer has already been resetted.
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
EisaCheckDeepReg
|
|||
|
(
|
|||
|
IN PUCHAR Port
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// define local variables
|
|||
|
//
|
|||
|
|
|||
|
UCHAR LSave, HSave, Program, LCheck, HCheck;
|
|||
|
BOOLEAN CompOk = TRUE;
|
|||
|
|
|||
|
PRINTDBG("EisaCheckDeepReg\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
//
|
|||
|
// save original value
|
|||
|
//
|
|||
|
|
|||
|
LSave = EisaInUchar( Port );
|
|||
|
HSave = EisaInUchar( Port );
|
|||
|
|
|||
|
//
|
|||
|
// one loop per each value
|
|||
|
//
|
|||
|
|
|||
|
for ( Program = 0; ; Program += 0x55 )
|
|||
|
{
|
|||
|
//
|
|||
|
// write port and read it back
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port, Program );
|
|||
|
EisaOutUchar( Port, Program );
|
|||
|
|
|||
|
EISA_IO_DELAY; //
|
|||
|
EISA_IO_DELAY; // for the timer chip
|
|||
|
EISA_IO_DELAY; //
|
|||
|
|
|||
|
LCheck = EisaInUchar( Port );
|
|||
|
HCheck = EisaInUchar( Port );
|
|||
|
|
|||
|
//
|
|||
|
// check the read values
|
|||
|
//
|
|||
|
|
|||
|
if ( LCheck != Program || HCheck != Program )
|
|||
|
{
|
|||
|
//
|
|||
|
// error, value are not the same
|
|||
|
//
|
|||
|
|
|||
|
CompOk = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// exit loop if last value
|
|||
|
//
|
|||
|
|
|||
|
if ( Program == 0xFF )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// restore the original value
|
|||
|
//
|
|||
|
|
|||
|
EisaOutUchar( Port, LSave );
|
|||
|
EisaOutUchar( Port, HSave );
|
|||
|
|
|||
|
return CompOk;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaReadRtc:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function returns the value of the specified
|
|||
|
// real-time clock internal address.
|
|||
|
//
|
|||
|
// ARGUMENTS: EisaIoStart EISA I/O virtual address
|
|||
|
// RtcIndex index within the RTC
|
|||
|
//
|
|||
|
// RETURN: Value register value
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
UCHAR
|
|||
|
EisaReadRtc
|
|||
|
(
|
|||
|
IN PUCHAR EisaIoStart,
|
|||
|
IN ULONG RtcIndex
|
|||
|
)
|
|||
|
{
|
|||
|
UCHAR Value;
|
|||
|
|
|||
|
PRINTDBG("EisaReadRtc\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
// NOTE: CriticalSection is not supported on JAZZ.
|
|||
|
// EisaBeginCriticalSection();
|
|||
|
EisaOutUchar( EisaIoStart + EISA_RTC_CTRL, RtcIndex );
|
|||
|
Value = READ_REGISTER_UCHAR( RTC_VIRTUAL_BASE );
|
|||
|
// EisaEndCriticalSection();
|
|||
|
|
|||
|
return Value;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaOutUchar:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function writes an uchar within the EISA I/O
|
|||
|
// space and delays before returning.
|
|||
|
//
|
|||
|
// ARGUMENTS: Addr Address where the value has to be
|
|||
|
// write to.
|
|||
|
// Value Value to write
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
EisaOutUchar
|
|||
|
(
|
|||
|
IN PUCHAR Addr,
|
|||
|
IN UCHAR Value
|
|||
|
)
|
|||
|
{
|
|||
|
// PRINTDBG("EisaOutUchar\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
WRITE_REGISTER_UCHAR( Addr, Value );
|
|||
|
EISA_IO_DELAY;
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
// PROCEDURE: EisaInUchar:
|
|||
|
//
|
|||
|
// DESCRIPTION: This function reads an uchar from the EISA I/O
|
|||
|
// space and delays before returning.
|
|||
|
//
|
|||
|
// ARGUMENTS: Addr Address where the value has to be
|
|||
|
// read from.
|
|||
|
//
|
|||
|
// RETURN: none
|
|||
|
//
|
|||
|
// ASSUMPTIONS:
|
|||
|
//
|
|||
|
// CALLS:
|
|||
|
//
|
|||
|
// GLOBALS:
|
|||
|
//
|
|||
|
// NOTES:
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
UCHAR
|
|||
|
EisaInUchar
|
|||
|
(
|
|||
|
IN PUCHAR Addr
|
|||
|
)
|
|||
|
{
|
|||
|
UCHAR Value;
|
|||
|
|
|||
|
// PRINTDBG("EisaInUchar\n\r"); // DEBUG SUPPORT
|
|||
|
|
|||
|
Value = READ_REGISTER_UCHAR( Addr );
|
|||
|
EISA_IO_DELAY;
|
|||
|
|
|||
|
return Value;
|
|||
|
}
|
|||
|
|
|||
|
|