290 lines
5.5 KiB
C
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);
|
|
}
|
|
}
|