1468 lines
37 KiB
C
1468 lines
37 KiB
C
/*++
|
||
|
||
Copyright (c) 1995 Digital Equipment Corporation
|
||
|
||
Module Name:
|
||
|
||
iod.c
|
||
|
||
Abstract:
|
||
|
||
This module implements functions that are specific to the IOD ASIC.
|
||
The IOD ASIC is a control ASIC for PCI on EV5-based Rawhide
|
||
systems.
|
||
|
||
Author:
|
||
|
||
Eric Rehm 12-Apr-1995
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
#include "halp.h"
|
||
#include "rawhide.h"
|
||
|
||
BOOLEAN IodInitialized = FALSE;
|
||
|
||
MC_DEVICE_MASK HalpIodMask = 0x0;
|
||
MC_DEVICE_MASK HalpCpuMask = 0x0;
|
||
MC_DEVICE_MASK HalpGcdMask = 0x0;
|
||
|
||
//
|
||
// Declare the IOD interrupt vector table and global pointer
|
||
// Due to the fact that the MC_DEVICE_ID specifies the 64
|
||
// byte offset into this global table, we must allocate
|
||
// full table for all
|
||
//
|
||
|
||
|
||
PIOD_POSTED_INTERRUPT HalpIodPostedInterrupts;
|
||
|
||
//
|
||
// Declare the PCI logical to physical mapping structure
|
||
//
|
||
|
||
MC_DEVICE_ID HalpIodLogicalToPhysical[RAWHIDE_MAXIMUM_PCI_BUS];
|
||
|
||
//
|
||
// The revision of the IOD. Software visible differences may exist between
|
||
// passes of the IOD. The revision is determined once at the start of
|
||
// run-time and used in places where the software must diverge.
|
||
//
|
||
|
||
IOD_PCI_REVISION HalpIodRevision;
|
||
|
||
//
|
||
// Declare routines local to this module
|
||
//
|
||
|
||
|
||
VOID
|
||
HalpInitializeBitMap (
|
||
IN PRTL_BITMAP BitMapHeader,
|
||
IN PULONG BitMapBuffer,
|
||
IN ULONG SizeOfBitMap
|
||
);
|
||
|
||
|
||
|
||
VOID
|
||
HalpInitializeIodMappingTable(
|
||
MC_DEVICE_ID McDeviceId,
|
||
ULONG PciBusNumber,
|
||
va_list Arguments
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This enumeration routine initialize the IOD logical to physical
|
||
mapping table. The Logical IOD number is via a static variable
|
||
that is incremented for each invokation of this routine.
|
||
|
||
Arguments:
|
||
|
||
McDeviceId - IOD device id to be mapped.
|
||
|
||
PciBusNumber - Logical PCI Bus number (unused).
|
||
|
||
Arguments - variable arguments. None for this routine.
|
||
|
||
Return Values:
|
||
|
||
None:
|
||
|
||
--*/
|
||
|
||
{
|
||
HalpIodLogicalToPhysical[PciBusNumber].all = 0;
|
||
HalpIodLogicalToPhysical[PciBusNumber].Gid = McDeviceId.Gid;
|
||
HalpIodLogicalToPhysical[PciBusNumber].Mid = McDeviceId.Mid;
|
||
|
||
#if HALDBG
|
||
DbgPrint("HalpIodLogicalToPhysical[%d] = %x\n",
|
||
PciBusNumber,
|
||
HalpIodLogicalToPhysical[PciBusNumber]);
|
||
#endif // HALDBG
|
||
|
||
}
|
||
|
||
VOID
|
||
HalpInitializeIodVectorTable(
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initialize the global pointer to the IOD vector table.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// Allocate the Global Iod vector table.
|
||
//
|
||
|
||
// mdbfix - we only need 4K, but require a page aligned
|
||
// address due to the fact that IOD uses target CPU's
|
||
// MC_DEVICE_ID as bits <11,6> of the vector table address
|
||
// in memory. So we allocate a PAGE more to guarantee
|
||
// a page aligned address.
|
||
//
|
||
|
||
HalpIodPostedInterrupts =
|
||
ExAllocatePool(
|
||
NonPagedPool,
|
||
__4K + __8K
|
||
);
|
||
|
||
#if HALDBG
|
||
DbgPrint("HalpIodPostedInterrupts = 0x%x\n", HalpIodPostedInterrupts);
|
||
#endif
|
||
|
||
if (HalpIodPostedInterrupts == NULL) {
|
||
|
||
DbgBreakPoint();
|
||
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
HalpInitializeIod(
|
||
MC_DEVICE_ID McDeviceId,
|
||
ULONG PciBusNumber,
|
||
va_list Arguments
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This enumeration routine initializes the corresponding IOD.
|
||
|
||
Arguments:
|
||
|
||
McDeviceId - Supplies the MC Bus Device ID of the IOD to be intialized
|
||
|
||
PciBusNumber - Logical PCI Bus number (unused).
|
||
|
||
Arguments - Variable arguments including:
|
||
|
||
1) LoaderBlock - Supplies a pointer to the loader parameter block.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
IOD_CAP_CONTROL IodCapControl;
|
||
IOD_CAP_ERR IodCapError;
|
||
IOD_WBASE Wbase;
|
||
IOD_TBASE Tbase;
|
||
IOD_WMASK Wmask;
|
||
IOD_TBIA Tbia;
|
||
IOD_MDPA_STAT IodMdpaStat;
|
||
IOD_MDPB_STAT IodMdpbStat;
|
||
IOD_MDPA_DIAG IodMdpaDiag;
|
||
IOD_MDPB_DIAG IodMdpbDiag;
|
||
PLOADER_PARAMETER_BLOCK LoaderBlock;
|
||
|
||
//
|
||
// Initialize parameters
|
||
//
|
||
|
||
// mdbfix - this is not used
|
||
// LoaderBlock = va_arg(Arguments, PLOADER_PARAMETER_BLOCK);
|
||
|
||
//
|
||
// Read the IOD revision.
|
||
//
|
||
|
||
HalpIodRevision.all =
|
||
READ_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->PciRevision );
|
||
|
||
#if HALDBG
|
||
|
||
DbgPrint( "Entry - HalpInitializeIod\n\n");
|
||
|
||
DbgPrint( "IOD (%x,%x) Revision: \n", McDeviceId.Gid, McDeviceId.Mid);
|
||
DbgPrint( "\tCAP = 0x%x\n", HalpIodRevision.CapRev );
|
||
DbgPrint( "\tHorse = 0x%x\n", HalpIodRevision.HorseRev );
|
||
DbgPrint( "\tSaddle = 0x%x\n", HalpIodRevision.SaddleRev );
|
||
DbgPrint( "\tSaddle Type = 0x%x\n", HalpIodRevision.SaddleType );
|
||
DbgPrint( "\tEISA Present = 0x%x\n", HalpIodRevision.EisaPresent );
|
||
DbgPrint( "\tPCI Class, Subclass = 0x%0.2x%0.2x\n",
|
||
HalpIodRevision.BaseClass, HalpIodRevision.SubClass );
|
||
|
||
#endif //HALDBG
|
||
|
||
//
|
||
// Initialize IOD Control. Currently, take the initial values
|
||
// set by the Extended SROM.
|
||
//
|
||
|
||
IodCapControl.all =
|
||
READ_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->CapCtrl );
|
||
|
||
#if HALDBG
|
||
|
||
DbgPrint( "Read Iod CAP Control = 0x%0.4x\n", IodCapControl.all );
|
||
|
||
#endif //HALDBG
|
||
|
||
|
||
#ifdef RISP //ecrfix
|
||
|
||
//
|
||
// For RISP, initialized as per Rawhide S/W Programmers Manual
|
||
//
|
||
|
||
IodCapControl.DlyRdEn = 1;
|
||
IodCapControl.PciMemEn = 1;
|
||
IodCapControl.PciReq64 = 1;
|
||
IodCapControl.PciAck64 = 1;
|
||
IodCapControl.PciAddrPe= 1;
|
||
IodCapControl.McCmdAddrPe= 1;
|
||
IodCapControl.McNxmEn = 1;
|
||
IodCapControl.McBusMonEn= 1;
|
||
IodCapControl.PendNum = 11; // 12 - [ (0 * 2) + 1 + (0 * 2)]
|
||
IodCapControl.RdType = 2;
|
||
IodCapControl.RlType = 2;
|
||
IodCapControl.RmType = 2;
|
||
IodCapControl.PartialWrEn = 0;
|
||
IodCapControl.ArbMode = 0;
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->CapCtrl,
|
||
IodCapControl.all );
|
||
#if HALDBG
|
||
|
||
IodCapControl.all =
|
||
READ_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->CapCtrl );
|
||
|
||
DbgPrint( "Read Iod CAP Control = 0x%0.4x\n (after sets)", IodCapControl.all );
|
||
|
||
#endif //HALDBG
|
||
|
||
#endif //RISP
|
||
|
||
|
||
//
|
||
// Disable all of the scatter/gather windows.
|
||
//
|
||
|
||
Wbase.all = 0;
|
||
Wbase.Wen = 0;
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W0base,
|
||
Wbase.all );
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W1base,
|
||
Wbase.all );
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W2base,
|
||
Wbase.all );
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W3base,
|
||
Wbase.all );
|
||
|
||
//
|
||
// Invalidate all of the TLB Entries.
|
||
//
|
||
|
||
Tbia.all = 0;
|
||
|
||
//
|
||
// Perform the invalidation.
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->Tbia,
|
||
Tbia.all );
|
||
|
||
//
|
||
// Clear any pending error bits in the IOD_CAP_ERR register:
|
||
//
|
||
|
||
IodCapError.all = 0; // Clear all bits
|
||
|
||
IodCapError.Perr = 1; // PCI bus perr detected
|
||
IodCapError.Serr = 1; // PCI bus serr detected
|
||
IodCapError.Mab = 1; // PCI bus master abort detected
|
||
IodCapError.PteInv = 1; // Invalid Pte
|
||
IodCapError.PioOvfl = 1; // Pio Ovfl
|
||
IodCapError.LostMcErr = 1; // Lost error
|
||
IodCapError.McAddrPerr = 1; // MC bus comd/addr parity error
|
||
IodCapError.Nxm = 1; // MC bus Non-existent memory error
|
||
IodCapError.CrdA = 1; // Correctable ECC error on MDPA
|
||
IodCapError.CrdB = 1; // Correctable ECC error on MDPB
|
||
IodCapError.RdsA = 1; // Uncorrectable ECC error on MDPA
|
||
IodCapError.RdsA = 1; // Uncorrectable ECC error on MDPA
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->CapErr,
|
||
IodCapError.all );
|
||
|
||
//
|
||
// Clear any ECC error syndrome bits in the IOD_MDPA/B_SYN registers:
|
||
//
|
||
|
||
IodMdpaStat.all = 0;
|
||
IodMdpaStat.Crd = 1; // Correctable ECC error (also clears Rds bit)
|
||
|
||
IodMdpbStat.all = 0;
|
||
IodMdpbStat.Crd = 1; // Correctable ECC error (also clears Rds bit)
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpaStat,
|
||
IodMdpaStat.all );
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpbStat,
|
||
IodMdpbStat.all );
|
||
|
||
#if 0 // CAP/MDP Bug
|
||
|
||
IodMdpaStat.all =
|
||
READ_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpaStat );
|
||
|
||
DbgPrint( "MDPA (%x,%x) Revision = 0x%x\n",
|
||
McDeviceId.Gid, McDeviceId.Mid, IodMdpaStat.MdpaRev);
|
||
|
||
IodMdpaStat.all =
|
||
READ_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpbStat );
|
||
|
||
DbgPrint( "MDPB (%x,%x) Revision = 0x%x\n",
|
||
McDeviceId.Gid, McDeviceId.Mid, IodMdpbStat.MdpbRev);
|
||
|
||
#endif
|
||
|
||
|
||
//
|
||
// Initialize MDP Diagnostic Checking. Currently just take the
|
||
// initial values set by the Extended SROM. Do both Mdpa and Mdpb.
|
||
//
|
||
|
||
#if 0 // CAP/MDP Bug
|
||
|
||
IodMdpaDiag.all =
|
||
READ_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpaDiag );
|
||
|
||
DbgPrint( "Read Iod MDPA Diag = 0x%0.4x\n", IodMdpaDiag.all );
|
||
|
||
IodMdpbDiag.all =
|
||
READ_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpbDiag );
|
||
|
||
DbgPrint( "Read Iod MDPB Diag = 0x%0.4x\n", IodMdpbDiag.all );
|
||
|
||
#endif
|
||
|
||
#if defined(AXP_FIRMWARE)
|
||
|
||
//
|
||
// Disable MCI bus interrupts
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntCtrl,
|
||
(IOD_INT_CTL_DISABLE_IO_INT | IOD_INT_CTL_DISABLE_VECT_WRITE)
|
||
);
|
||
|
||
//
|
||
// Clear interrupt request register (New for CAP Rev2.3)
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntReq,
|
||
IodIntMask
|
||
);
|
||
|
||
//
|
||
// Clear all pending interrupts for this IOD
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_INT_CSRS)IOD_INT_CSRS_QVA)->IntAck0,
|
||
0x0
|
||
);
|
||
|
||
//
|
||
// Clear all pending EISA interrupts for IOD 0
|
||
//
|
||
|
||
if ( (McDeviceId.Gid == GidPrimary) && (McDeviceId.Mid == MidPci0) ) {
|
||
|
||
INTERRUPT_ACKNOWLEDGE((PVOID)IOD_PCI0_IACK_QVA);
|
||
|
||
}
|
||
|
||
//
|
||
// Write the target register.
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntTarg,
|
||
(GidPrimary << 9)|(MidCpu1 << 6)|
|
||
(GidPrimary << 3)|(MidCpu0)
|
||
);
|
||
|
||
//
|
||
// Initialize the mask bits for target 0 and 1
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
(PVOID)&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntMask0,
|
||
0
|
||
);
|
||
|
||
WRITE_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
(PVOID)&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntMask1,
|
||
0
|
||
);
|
||
|
||
#endif //if defined(AXP_FIRMWARE)
|
||
|
||
IodInitialized = TRUE;
|
||
|
||
}
|
||
|
||
VOID
|
||
HalpClearAllIods(
|
||
IOD_CAP_ERR IodCapErrMask
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Clears specified CapErr bits on all IODs.
|
||
|
||
Arguments:
|
||
|
||
IodCapErrMask - Mask of bits to be cleared in each IOD_CAP_ERR.
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
|
||
MC_ENUM_CONTEXT mcCtx;
|
||
ULONG numIods;
|
||
BOOLEAN bfoundIod;
|
||
IOD_CAP_ERR IodCapErr;
|
||
|
||
|
||
//
|
||
// Clear all the error conditions in CAP_ERR on all IODs
|
||
// (Note - on 2 Mb Cached CPU, LostMcErr may also be set, so
|
||
// clear everything to be fer-sure, fer-sure.)
|
||
//
|
||
|
||
numIods = HalpMcBusEnumStart ( HalpIodMask, &mcCtx );
|
||
|
||
//
|
||
// Clear all errors on all IODs.
|
||
//
|
||
|
||
while ( bfoundIod = HalpMcBusEnum( &mcCtx ) ) {
|
||
|
||
//
|
||
// Read it
|
||
//
|
||
|
||
IodCapErr.all = READ_IOD_REGISTER_NEW( mcCtx.McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->CapErr );
|
||
|
||
//
|
||
// Mask it.
|
||
//
|
||
|
||
IodCapErr.all &= IodCapErrMask.all;
|
||
|
||
//
|
||
// If there is anything to clear, then do it.
|
||
//
|
||
|
||
if (IodCapErr.all != 0) {
|
||
|
||
WRITE_IOD_REGISTER_NEW( mcCtx.McDeviceId,
|
||
&((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->CapErr,
|
||
IodCapErr.all );
|
||
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
HalpInitializeIodVectorCSRs(
|
||
MC_DEVICE_ID McDeviceId,
|
||
ULONG PciBusNumber,
|
||
va_list Arguments
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This enumeration routine initializes Interrupt Vector Table CSRS
|
||
for the corresponding IOD.
|
||
|
||
The address used by an IOD during interrupt vector writes
|
||
is:
|
||
|
||
39 38 32 31 12 11 6 5 2 1 0
|
||
| | | | | | | | | | |
|
||
===================================================================
|
||
|0 | INT_ADDR_EXT | INT_ADDR_LO | TARGET ID | PCI BUS OFFSET | 00 |
|
||
===================================================================
|
||
|
||
Where:
|
||
INT_ADDR_EXT = 0 since our table resides in KSEG0_BASE.
|
||
INT_ADDR_LO = upper 20 bits (4K Page Addr) of Table Physical Address
|
||
TARGET_ID = MC_DEVICE_ID of Target CPU obtained from INT_TARG(0|1)
|
||
PCI_BUS_OFFSET = Logical PCI bus number used as an offset into vector
|
||
table by the interrupting IOD.
|
||
|
||
The assignment of PCI_BUS_OFFSET is based on the PCI bus number static
|
||
variable. This number is incremented with each invokation of this routine.
|
||
|
||
Arguments:
|
||
|
||
McDeviceId - Supplies the MC Bus Device ID of the IOD to be intialized
|
||
|
||
PciBusNumber - Logical PCI Bus number (unused).
|
||
|
||
Arguments - Variable Arguments. None for this routine.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
IOD_INT_ADDR IodIntAddr;
|
||
IOD_INT_ADDR_EXT IodIntAddrExt;
|
||
IOD_INT_CONTROL IodIntControl;
|
||
|
||
//
|
||
// Initialize the Interrupt Vector Table Address register
|
||
// for this IOD.
|
||
//
|
||
|
||
IodIntAddr.all =
|
||
READ_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntAddr );
|
||
|
||
IodIntAddr.Reserved1 = 0; // MBZ
|
||
IodIntAddr.PciOffset = PciBusNumber; // Logical IOD #
|
||
IodIntAddr.Reserved2 = 0; // MBZ
|
||
IodIntAddr.IntAddrLo = ((ULONG)HalpIodPostedInterrupts / __4K);
|
||
|
||
//
|
||
// Mask off the KSEG0_BASE to convert this to a physical
|
||
// address.
|
||
//
|
||
|
||
IodIntAddr.all &= ~KSEG0_BASE;
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntAddr,
|
||
IodIntAddr.all );
|
||
|
||
//
|
||
// Initialize the interrupt vector table Address Extension
|
||
// register to zero since our address resides in KSEG0_BASE.
|
||
//
|
||
|
||
IodIntAddrExt.all =
|
||
READ_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntAddrExt );
|
||
|
||
IodIntAddrExt.all = 0;
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
&((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntAddrExt,
|
||
IodIntAddrExt.all );
|
||
}
|
||
|
||
|
||
VOID
|
||
HalpIodInitializeSfwWindow(
|
||
// ecrfix MC_DEVICE_ID McDeviceId,
|
||
PWINDOW_CONTROL_REGISTERS WindowRegisters,
|
||
IOD_WINDOW_NUMBER WindowNumber
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initialize the DMA Control software window registers for the specified
|
||
DMA Window.
|
||
|
||
Arguments:
|
||
|
||
WindowRegisters - Supplies a pointer to the software window control.
|
||
|
||
WindowNumber - Supplies the window number initialized. (0 = Isa Dma
|
||
Window, 1 = Master Dma Window).
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
|
||
switch( WindowNumber ){
|
||
|
||
//
|
||
// The ISA DMA Window.
|
||
//
|
||
|
||
case IodIsaWindow:
|
||
|
||
WindowRegisters->WindowBase = (PVOID)ISA_DMA_WINDOW_BASE;
|
||
WindowRegisters->WindowSize = ISA_DMA_WINDOW_SIZE;
|
||
WindowRegisters->TranslatedBaseRegister =
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->T1base;
|
||
WindowRegisters->WindowBaseRegister =
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W1base;
|
||
WindowRegisters->WindowMaskRegister =
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W1mask;
|
||
WindowRegisters->WindowTbiaRegister =
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->Tbia;
|
||
|
||
break;
|
||
|
||
case IodMasterWindow:
|
||
|
||
WindowRegisters->WindowBase = (PVOID)MASTER_DMA_WINDOW_BASE;
|
||
WindowRegisters->WindowSize = MASTER_DMA_WINDOW_SIZE;
|
||
WindowRegisters->TranslatedBaseRegister =
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->T0base;
|
||
WindowRegisters->WindowBaseRegister =
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W0base;
|
||
WindowRegisters->WindowMaskRegister =
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W0mask;
|
||
WindowRegisters->WindowTbiaRegister =
|
||
&((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->Tbia;
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
#if HALDBG
|
||
|
||
DbgPrint( "IodInitializeSfwWindow: Bad Window Number = %x\n",
|
||
WindowNumber );
|
||
|
||
#endif //HALDBG
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
HalpIodProgramDmaWindow(
|
||
PWINDOW_CONTROL_REGISTERS WindowRegisters,
|
||
PVOID MapRegisterBase
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Program the control windows in the hardware so that DMA can be started
|
||
to the DMA window.
|
||
|
||
Arguments:
|
||
|
||
WindowRegisters - Supplies a pointer to the software window register
|
||
control structure.
|
||
|
||
MapRegisterBase - Supplies the logical address of the scatter/gather
|
||
array in system memory.
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
IOD_WBASE Wbase;
|
||
IOD_TBASE Tbase;
|
||
IOD_WMASK Wmask;
|
||
IOD_TBIA Tbia;
|
||
|
||
MC_ENUM_CONTEXT mcCtx;
|
||
MC_DEVICE_ID McDeviceId;
|
||
|
||
//
|
||
// Program the windows as specified by the caller.
|
||
//
|
||
|
||
Wbase.all = 0;
|
||
Wbase.Wen = 1;
|
||
Wbase.SgEn = 1;
|
||
Wbase.Wbase = (ULONG)(WindowRegisters->WindowBase) >> 20;
|
||
|
||
Wmask.all = 0;
|
||
Wmask.Wmask = (WindowRegisters->WindowSize >> 20) - 1;
|
||
|
||
Tbase.all = 0;
|
||
Tbase.Tbase = (ULONG)MapRegisterBase >> 10;
|
||
|
||
Tbia.all = 0;
|
||
|
||
//
|
||
// Dump the IOD registers.
|
||
//
|
||
|
||
#if HALDBG
|
||
|
||
// DumpAllIods( IodScatterGatherRegisters );
|
||
|
||
#endif //HALDBG
|
||
|
||
//
|
||
// Loop through all of the Iods
|
||
//
|
||
// ecrfix - is it OK to do it one at a time this way?
|
||
//
|
||
|
||
HalpMcBusEnumStart( HalpIodMask, &mcCtx );
|
||
|
||
while ( HalpMcBusEnum ( &mcCtx ) ) {
|
||
|
||
McDeviceId = mcCtx.McDeviceId;
|
||
|
||
//
|
||
// Clear the window base, temporarily disabling transactions to this
|
||
// DMA window.
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
WindowRegisters->WindowBaseRegister, 0 );
|
||
|
||
//
|
||
// Now program the window by writing the translated base, then the size
|
||
// of the window in the mask register and finally the window base,
|
||
// enabling both the window and scatter gather.
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
WindowRegisters->TranslatedBaseRegister,
|
||
Tbase.all );
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
WindowRegisters->WindowMaskRegister,
|
||
Wmask.all );
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
WindowRegisters->WindowBaseRegister,
|
||
Wbase.all );
|
||
|
||
//
|
||
// Flush the volatile entries in this IOD's scatter/gather Tlb.
|
||
//
|
||
|
||
WRITE_IOD_REGISTER_NEW( McDeviceId,
|
||
WindowRegisters->WindowTbiaRegister,
|
||
Tbia.all );
|
||
}
|
||
|
||
// ecrfix - we did it above. HalpIodInvalidateTlb( WindowRegisters );
|
||
|
||
//
|
||
// Dump the IOD registers.
|
||
//
|
||
|
||
#if HALDBG
|
||
|
||
// DumpAllIods( IodScatterGatherRegisters | IodGeneralRegisters );
|
||
|
||
#endif //HALDBG
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
ULONG
|
||
HalpMcBusEnumStart(
|
||
MC_DEVICE_MASK McDeviceMask,
|
||
PMC_ENUM_CONTEXT McContext
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Given a particular MC Bus device mask:
|
||
|
||
* Set up state so that subsequent MC Bus devices can be enumerated
|
||
by calling HalpMcBusEnum( McContext ).
|
||
|
||
* Return the first MC_DEVICE_ID in that mask via McContext.
|
||
(ECRFIX: IFDEF out for now!)
|
||
|
||
N.B. The search will start with GID = 7, i.e., McDeviceMask<56>
|
||
because the primary GID is 7.
|
||
|
||
Arguments:
|
||
|
||
McDeviceMask - Supplies a bitfield of MC Bus devices to be enumerated.
|
||
|
||
McContext - A structure that contains the MC_DEVICE_ID to be enumerated
|
||
and associated enumerator state.
|
||
|
||
|
||
Return Value:
|
||
|
||
Number of MC Bus devices to be enumerated.
|
||
|
||
--*/
|
||
{
|
||
ULONG count;
|
||
|
||
//
|
||
// Intialize the bitmap from the McDeviceMask.
|
||
// (Make a copy so that McDeviceMask is preserved for the caller.)
|
||
//
|
||
|
||
McContext->tempMask = McDeviceMask;
|
||
|
||
// RtlInitializeBitMap(&McContext->McDeviceBitmap,
|
||
HalpInitializeBitMap(&McContext->McDeviceBitmap,
|
||
(PULONG) &McContext->tempMask,
|
||
sizeof(MC_DEVICE_MASK) * 8);
|
||
|
||
//
|
||
// Count the number of device to be enuerated
|
||
//
|
||
|
||
count = HalpNumberOfSetBits (&McContext->McDeviceBitmap);
|
||
|
||
//
|
||
|
||
// Start looking at GID = 7.
|
||
//
|
||
|
||
McContext->nextBit = GidPrimary * 8;
|
||
|
||
#if 0
|
||
//
|
||
// Find the first MC Bus device to be enumerated.
|
||
//
|
||
|
||
McContext->nextBit = HalpFindSetBitsAndClear (&McContext->McDeviceBitmap,
|
||
1,
|
||
McContext->nextBit);
|
||
|
||
//
|
||
// Convert first non-zero bit found to MC_DEVICE_ID
|
||
//
|
||
|
||
McContext->McDeviceId.all = 0;
|
||
McContext->McDeviceId.Gid = McContext->nextBit / 8;
|
||
McContext->McDeviceId.Mid = McContext->nextBit % 8;
|
||
#endif
|
||
|
||
return ( count );
|
||
|
||
}
|
||
|
||
BOOLEAN
|
||
HalpMcBusEnum(
|
||
PMC_ENUM_CONTEXT McContext
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Enumerate MC Bus devices until none are left
|
||
|
||
Arguments:
|
||
|
||
McContext - A structure that contains the MC_DEVICE_ID to be enumerated
|
||
and associated enumerator state.
|
||
|
||
|
||
Return Value:
|
||
|
||
TRUE, unless there were no more MC Bus devices to be enumerated,
|
||
in which case, returns FALSE.
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// Find the next MC Bus device.
|
||
//
|
||
|
||
McContext->nextBit = HalpFindSetBitsAndClear (&McContext->McDeviceBitmap,
|
||
1,
|
||
McContext->nextBit);
|
||
|
||
if ( McContext->nextBit != 0xffffffff) {
|
||
|
||
//
|
||
// Convert the non-zero bit found to MC_DEVICE_ID
|
||
//
|
||
|
||
McContext->McDeviceId.all = 0;
|
||
McContext->McDeviceId.Gid = McContext->nextBit / 8;
|
||
McContext->McDeviceId.Mid = McContext->nextBit % 8;
|
||
|
||
//
|
||
// Since we just set nextBit to zero, we can start the
|
||
// next search one bit higher. This will speed up the
|
||
// next call to HalpMcBusEnum.
|
||
//
|
||
|
||
McContext->nextBit++;
|
||
|
||
return ( TRUE );
|
||
|
||
} else {
|
||
|
||
return ( FALSE) ;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
HalpMcBusEnumAndCall(
|
||
MC_DEVICE_MASK McDeviceMask,
|
||
PMC_ENUM_ROUTINE McBusEnumRoutine,
|
||
...
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Execute the Call routine for all devices in the MC device mask.
|
||
This routine provides a general method to enumerate an MC_DEVICE_MASK
|
||
and execute a caller-supplied routine for each device. A logical
|
||
device number and variable arguments are passed to the routine.
|
||
|
||
Arguments:
|
||
|
||
McDeviceMask - Supplies a bitfield of MC Bus devices to be enumerated.
|
||
|
||
McBusEnumRoutine - Routine that is called for each MC Bus device.
|
||
|
||
... - Variable arguments passed by the caller.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
MC_ENUM_CONTEXT mcCtx;
|
||
ULONG numIods;
|
||
ULONG LogicalDeviceNumber = 0;
|
||
va_list Arguments;
|
||
|
||
//
|
||
// Intialize enumerator.
|
||
//
|
||
|
||
numIods = HalpMcBusEnumStart ( McDeviceMask, &mcCtx );
|
||
|
||
//
|
||
// Execute routine for each device.
|
||
//
|
||
|
||
while ( HalpMcBusEnum( &mcCtx ) ) {
|
||
va_start(Arguments, McBusEnumRoutine);
|
||
McBusEnumRoutine( mcCtx.McDeviceId, LogicalDeviceNumber++, Arguments );
|
||
va_end(Arguments);
|
||
}
|
||
}
|
||
|
||
|
||
ULONG
|
||
HalpReadWhoAmI(
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Read the WHOAMI register.
|
||
Arguments:
|
||
|
||
None.
|
||
Return Value:
|
||
|
||
The value of the WHOAMI.
|
||
|
||
--*/
|
||
{
|
||
|
||
MC_DEVICE_ID McDeviceId;
|
||
IOD_WHOAMI IodWhoAmI;
|
||
|
||
|
||
//
|
||
// Initialize Id for IOD 0.
|
||
//
|
||
|
||
McDeviceId.all = 0;
|
||
McDeviceId.Gid = GidPrimary;
|
||
McDeviceId.Mid = MidPci0;
|
||
|
||
|
||
return (
|
||
READ_IOD_REGISTER_NEW(
|
||
McDeviceId,
|
||
&((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->WhoAmI )
|
||
);
|
||
|
||
}
|
||
|
||
|
||
VOID
|
||
HalpIodInvalidateTlb(
|
||
PWINDOW_CONTROL_REGISTERS WindowRegisters
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Invalidate the DMA Scatter/Gather TLB in all the IODs.
|
||
The TLB is invalidated whenever the scatter/gather translation
|
||
entries are modified.
|
||
|
||
Arguments:
|
||
|
||
WindowRegisters - Supplies a pointer to the software window register
|
||
control structure.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
|
||
//
|
||
// Perform the S/G TLB invalidation
|
||
//
|
||
|
||
IOD_TBIA Tbia;
|
||
MC_ENUM_CONTEXT mcCtx;
|
||
|
||
Tbia.all = 0;
|
||
|
||
HalpMcBusEnumStart(HalpIodMask, &mcCtx);
|
||
|
||
while ( HalpMcBusEnum( &mcCtx ) ) {
|
||
|
||
WRITE_IOD_REGISTER_NEW( mcCtx.McDeviceId,
|
||
WindowRegisters->WindowTbiaRegister,
|
||
Tbia.all );
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
#if HALDBG || DUMPIODS
|
||
|
||
IOD_REGISTER_CLASS DumpIodFlag = AllRegisters;
|
||
|
||
VOID
|
||
DumpAllIods(
|
||
IOD_REGISTER_CLASS RegistersToDump
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Read the interesting Iod registers and print them to the debug port.
|
||
|
||
Arguments:
|
||
|
||
McDeviceId - Supplies the MC Bus Device ID of the IOD to be dumped
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
MC_ENUM_CONTEXT mcCtx;
|
||
ULONG NumIods;
|
||
|
||
DbgPrint( "Dump All IODs: \n" );
|
||
|
||
NumIods = HalpMcBusEnumStart(HalpIodMask, &mcCtx);
|
||
|
||
DbgPrint( "Dump All IODs: (%d IODs)\n", NumIods );
|
||
|
||
while ( HalpMcBusEnum( &mcCtx ) ) {
|
||
|
||
DumpIod( mcCtx.McDeviceId,
|
||
RegistersToDump );
|
||
}
|
||
|
||
|
||
}
|
||
|
||
VOID
|
||
DumpIod(
|
||
MC_DEVICE_ID McDeviceId,
|
||
IOD_REGISTER_CLASS RegistersToDump
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Read the interesting Iod registers and print them to the debug port.
|
||
|
||
Arguments:
|
||
|
||
McDeviceId - Supplies the MC Bus Device ID of the IOD to be dumped
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PVOID RegisterQva;
|
||
ULONG Value;
|
||
|
||
DbgPrint( "IOD (%x, %x) Register Dump: \n", McDeviceId.Gid, McDeviceId.Mid );
|
||
|
||
//
|
||
// Dump the IOD General Control registers.
|
||
//
|
||
|
||
if( (RegistersToDump & IodGeneralRegisters) != 0 ){
|
||
|
||
RegisterQva = &((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->PciRevision;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IodRevision = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->WhoAmI;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "WhoAmI = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->PciLat;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "PciLat = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->CapCtrl;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IodCtrl = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->HaeMem;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "HaeMem = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->HaeIo;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "HaeIo = 0x%x\n", Value );
|
||
|
||
#if 0 // ecrfix - don't read this on PCI0 - creates an IACK cycle
|
||
// on the EISA bus. Don't read this on PCI1,2,3, because
|
||
// (apparently), it doesn't exist there.
|
||
|
||
RegisterQva = &((PIOD_GENERAL_CSRS)(IOD_GENERAL_CSRS_QVA))->IackSc;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IackSc = 0x%x\n", Value );
|
||
#endif
|
||
|
||
}
|
||
|
||
//
|
||
// Dump the IOD Interrupt registers.
|
||
//
|
||
|
||
if( (RegistersToDump & IodInterruptRegisters) != 0 ){
|
||
|
||
RegisterQva = &((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntCtrl;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IntCtrl = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntReq;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IntReq = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntTarg;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IntTarg = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntAddr;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IntAddr = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntAddrExt;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IntAddrExt = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntMask0;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IntMask0 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_INT_CSRS)(IOD_INT_CSRS_QVA))->IntMask1;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "IntMask1 = 0x%x\n", Value );
|
||
|
||
|
||
}
|
||
|
||
//
|
||
// Dump the IOD Diagnostic registers.
|
||
//
|
||
|
||
if( (RegistersToDump & IodDiagnosticRegisters) != 0 ){
|
||
|
||
RegisterQva = &((PIOD_DIAG_CSRS)(IOD_DIAG_CSRS_QVA))->CapDiag;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "CapDiag = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_DIAG_CSRS)(IOD_DIAG_CSRS_QVA))->Scratch;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "Scratch = 0x%x\n", Value );
|
||
|
||
}
|
||
|
||
//
|
||
// Dump the IOD Error registers.
|
||
//
|
||
|
||
if( (RegistersToDump & IodErrorRegisters) != 0 ){
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->McErr0;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "MCErr0 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->McErr1;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "MCErr1 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->CapErr;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "CapErr = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->PciErr1;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "PciErr1 = 0x%x\n", Value );
|
||
|
||
#if 0 // CAP/MDP Bug
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpaStat;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "MdpaStat = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpaSyn;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "MdpaSyn = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpaDiag;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "MdpaDiag = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpbStat;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "MdpbStat = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpbSyn;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "MdpbSyn = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_ERROR_CSRS)(IOD_ERROR_CSRS_QVA))->MdpbDiag;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "MdpbDiag = 0x%x\n", Value );
|
||
#endif
|
||
}
|
||
|
||
//
|
||
// Dump the PCI Scatter/Gather registers.
|
||
//
|
||
|
||
if( (RegistersToDump & IodScatterGatherRegisters) != 0 ){
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->Tbia;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "Tbia = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->Hbase;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "Hbase = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W0base;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "W0base = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W0mask;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "W0mask = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->T0base;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "T0base = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W1base;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "W1base = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W1mask;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "W1mask = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->T1base;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "T1base = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W2base;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "W2base = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W2mask;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "W2mask = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->T2base;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "T2base = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W3base;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "W3base = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->W3mask;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "W3mask = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->T3base;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "T3base = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->Wdac;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "Wdac = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->TbTag0;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "TbTag0 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->TbTag1;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "TbTag1 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->TbTag2;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "TbTag2 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->TbTag3;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "TbTag3 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->TbTag4;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "TbTag4 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->TbTag5;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "TbTag5 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->TbTag6;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "TbTag6 = 0x%x\n", Value );
|
||
|
||
RegisterQva = &((PIOD_SG_CSRS)(IOD_SG_CSRS_QVA))->TbTag7;
|
||
Value = READ_IOD_REGISTER_NEW( McDeviceId, RegisterQva );
|
||
DbgPrint( "TbTag7 = 0x%x\n", Value );
|
||
}
|
||
|
||
//
|
||
// Dump the IOD Reset register.
|
||
//
|
||
|
||
if( (RegistersToDump & IodResetRegister) != 0 ){
|
||
|
||
RegisterQva = (PIOD_ELCR1)((ULONG)HalpEisaControlBase + 27);
|
||
Value = (ULONG) READ_PORT_UCHAR( (PUCHAR) RegisterQva );
|
||
DbgPrint( "ELCR2 = 0x%x\n", Value );
|
||
|
||
}
|
||
|
||
|
||
DbgPrint( "--end IOD Register dump\n\n" );
|
||
|
||
return;
|
||
|
||
}
|
||
|
||
#endif //HALDBG || DUMPIODS
|
||
|