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