NT4/private/ntos/nthals/halr98mp/mips/r98pci.c
2020-09-30 17:12:29 +02:00

290 lines
5.5 KiB
C

#ident "@(#) NEC r98pci.c 1.8 95/01/11 22:30:24"
/*++
Copyright (c) 1994 Kobe NEC Software
Module Name:
r98pci.c
Abstract:
This module implements the pci bus support routine for R98
Author:
Environment:
Kernel mode
Revision History:
S001 94.7/20 T.Samezima
Chg Del compile err
S002 '94.10/14 T.Samezima
Add Set PCI bus interrupt affinity.
S003 '94.10/24 T.Samezima
Add Error register read and print.
S004 '94.12/07 T.Samezima
Add Error register read and print.
S005 '94.01/11 T.Samezima
Del del werning.
--*/
#include "halp.h"
#include "stdio.h" // S005
//
// Enable PCI count
//
ULONG HalpEnablePCIInterruptCount;
// Start S002
// Define PCI bus interrupt affinity.
//
KAFFINITY HalpPCIBusAffinity;
// End S002
// S001
BOOLEAN
HalpPCIDispatch( // S001
IN PKINTERRUPT Interrupt
)
/*++
Routine Description:
This routine is entered as the result of PCI err interrupt.
Arguments:
Interrupt - Supplies a pointer to the interrupt function address.
Return Value:
--*/
{
// S003 vvv
// S004 vvv
ULONG errsBuffer;
ULONG pearBuffer;
ULONG aearBuffer;
UCHAR messageBuffer[256];
errsBuffer = READ_REGISTER_ULONG( &( LR_CONTROL1 )->ERRS );
pearBuffer = READ_REGISTER_ULONG( &( LR_PCI_DEV_REG_CONTROL )->PEAR );
aearBuffer = READ_REGISTER_ULONG( &( LR_PCI_DEV_REG_CONTROL )->AEAR );
if ( errsBuffer & 0x80000000 ) {
sprintf( (char *)messageBuffer,
"PCI Bus: Master Abort: PEAR=0x%08lX\n",
pearBuffer
);
HalDisplayString( (char *)messageBuffer );
KdPrint(( (char *)messageBuffer ));
}
if ( errsBuffer & 0x40000000 ) {
sprintf( (char *)messageBuffer,
"PCI Bus: Target Abort: PEAR=0x%08lX\n",
pearBuffer
);
HalDisplayString( (char *)messageBuffer );
KdPrint(( (char *)messageBuffer ));
}
if ( errsBuffer & 0x20000000 ) {
sprintf( (char *)messageBuffer,
"PCI Bus: System error\n"
);
HalDisplayString( (char *)messageBuffer );
KdPrint(( (char *)messageBuffer ));
}
if ( errsBuffer & 0x10000000 ) {
sprintf( (char *)messageBuffer,
"PCI Bus: Parity error\n"
);
HalDisplayString( (char *)messageBuffer );
KdPrint(( (char *)messageBuffer ));
}
if ( errsBuffer & 0x08000000 ) {
sprintf( (char *)messageBuffer,
"Page fault in NA Bus master transaction\n"
" ERRS=0x%08lX, AEAR=0x%08lX\n",
errsBuffer,
aearBuffer
);
HalDisplayString( (char *)messageBuffer );
KdPrint(( (char *)messageBuffer ));
}
// S004 ^^^
KeBugCheckEx(DATA_BUS_ERROR,
READ_REGISTER_ULONG( &( LR_CONTROL1 )->ERRS ),
READ_REGISTER_ULONG( &( LR_PCI_DEV_REG_CONTROL )->PEAR ),
READ_REGISTER_ULONG( &( LR_PCI_DEV_REG_CONTROL )->AEAR ),
0 );
// S003 ^^^
return TRUE;
}
BOOLEAN
HalpCreatePciStructures (
VOID
)
/*++
Routine Description:
This routine initializes the structures necessary for PCI operations
and connects the intermediate interrupt dispatcher.
Arguments:
None.
Return Value:
If the second level interrupt dispatcher is connected, then a value of
TRUE is returned. Otherwise, a value of FALSE is returned.
--*/
{
//
// Initialize the interrupt dispatcher for PCI err interrupts.
//
PCR->InterruptRoutine[PCI_ERR_VECTOR] = (PKINTERRUPT_ROUTINE) HalpPCIDispatch;
// Start S002
// Set PCI bus interrupt affinity.
//
HalpPCIBusAffinity = PCR->SetMember;
// End S002
//
// Enable PCI err interrupt
//
KiAcquireSpinLock(&HalpSystemInterruptLock);
HalpBuiltinInterruptEnable |= iREN_ENABLE_PCI_ERR_INTERRUPT;
WRITE_REGISTER_ULONG( &( LR_CONTROL2 )->iREN,
HalpBuiltinInterruptEnable);
KiReleaseSpinLock(&HalpSystemInterruptLock);
return TRUE;
}
VOID
HalpEnablePciInterrupt(
IN ULONG Vector
)
/*++
Routine Description:
This function enables the PCI bus specified PCI bus interrupt.
memo: This routine enter following condition
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
KiAcquireSpinLock(&HalpSystemInterruptLock);
Arguments:
Vector - Supplies the vector of the PCI interrupt that is enabled.
Return Value:
None.
--*/
{
//
// Count up enable count
//
HalpEnablePCIInterruptCount++;
//
// Check interrupt enable count. if interrupt is not already enable, then
// enable PCI interrupt.
//
if(HalpEnablePCIInterruptCount == 1){
HalpBuiltinInterruptEnable |= iREN_ENABLE_PCI_INTERRUPT;
WRITE_REGISTER_ULONG( &( LR_CONTROL2 )->iREN,
HalpBuiltinInterruptEnable);
}
}
VOID
HalpDisablePciInterrupt(
IN ULONG Vector
)
/*++
Routine Description:
This function disables the PCI bus specified PCI bus interrupt.
memo: This routine enter following condition
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
KiAcquireSpinLock(&HalpSystemInterruptLock);
Arguments:
Vector - Supplies the vector of the PCI interrupt that is Disabled.
Return Value:
None.
--*/
{
//
// Count down enable count
//
if( HalpEnablePCIInterruptCount > 0){
--HalpEnablePCIInterruptCount;
}
//
// Check interrupt enable count. if count equal zero, then disable
// PCI interrupt.
//
if(HalpEnablePCIInterruptCount == 0){
HalpBuiltinInterruptEnable &= ~iREN_ENABLE_PCI_INTERRUPT;
WRITE_REGISTER_ULONG( &( LR_CONTROL2 )->iREN,
HalpBuiltinInterruptEnable);
}
}