mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
3.0 KiB
146 lines
3.0 KiB
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation, Digital Equipment Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
pcibus.c
|
|
|
|
Abstract:
|
|
|
|
Platform-specific PCI bus routines
|
|
|
|
Author:
|
|
|
|
Eric Rehm 6-June-1995
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
#include "pci.h"
|
|
#include "pcip.h"
|
|
#include "machdep.h"
|
|
|
|
|
|
extern ULONG PCIMaxBus;
|
|
|
|
|
|
|
|
PCI_CONFIGURATION_TYPES
|
|
HalpPCIConfigCycleType (
|
|
IN PBUS_HANDLER BusHandler
|
|
)
|
|
{
|
|
PCI_CONFIGURATION_TYPES ConfigType;
|
|
ULONG BusNumber = BusHandler->BusNumber;
|
|
PPCIPBUSDATA BusData;
|
|
BOOLEAN BusIsAcrossPPB;
|
|
|
|
//
|
|
// Get a pointer to the bus-specific data.
|
|
//
|
|
|
|
BusData = (PPCIPBUSDATA)BusHandler->BusData;
|
|
|
|
//
|
|
// Get the flag that tells use whether this is
|
|
// a root bus or not.
|
|
//
|
|
|
|
BusIsAcrossPPB = BusData->BusIsAcrossPPB;
|
|
|
|
//
|
|
// Valid Config cycles for Bus # < PCIMaxBus
|
|
//
|
|
// Then, Type 1 config cycles only when bus is across
|
|
// a PPB.
|
|
//
|
|
|
|
if (BusNumber < PCIMaxBus) {
|
|
ConfigType = PciConfigType0;
|
|
if (BusIsAcrossPPB == TRUE)
|
|
{
|
|
ConfigType = PciConfigType1;
|
|
}
|
|
} else {
|
|
ConfigType = PciConfigTypeInvalid;
|
|
}
|
|
|
|
#if HALDBG
|
|
DbgPrint("BusNumber %d BusIsAcrossPPB %d ConfigType %d\n",
|
|
BusNumber, BusIsAcrossPPB, ConfigType);
|
|
#endif
|
|
|
|
return ConfigType;
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
HalpPCIConfigAddr (
|
|
IN PBUS_HANDLER BusHandler,
|
|
IN PCI_SLOT_NUMBER Slot,
|
|
PPCI_CFG_CYCLE_BITS pPciAddr
|
|
)
|
|
{
|
|
PCI_CONFIGURATION_TYPES ConfigType;
|
|
MC_DEVICE_ID McDevid;
|
|
ULONG BusNumber = BusHandler->BusNumber;
|
|
PPCIPBUSDATA BusData;
|
|
|
|
ConfigType = HalpPCIConfigCycleType(BusHandler);
|
|
|
|
//
|
|
// Get a pointer to the bus-specific data.
|
|
//
|
|
|
|
BusData = (PPCIPBUSDATA)BusHandler->BusData;
|
|
|
|
#if HALDBG
|
|
|
|
DbgPrint( "PCI Config Access: Bus = %d, Device = %d, BusIsAcrossPPB %d ConfigType = %d\n",
|
|
BusNumber, Slot.u.bits.DeviceNumber, BusData->BusIsAcrossPPB, ConfigType );
|
|
|
|
#endif //HALDBG
|
|
|
|
//
|
|
// From the root bus number (a.k.a. HwBusNumber), get
|
|
// the MC_DEVICE_ID of the IOD that we're attempting to access.
|
|
//
|
|
|
|
McDevid = HalpIodLogicalToPhysical[BusData->HwBusNumber];
|
|
|
|
//
|
|
// If this is an access to an PCI device on a root bus,
|
|
// then we want to generate a Type 0 config cycle. To do this
|
|
// on Rawhide, you must set BusNumber to zero.
|
|
//
|
|
// We know that an access is destined to a root bus when
|
|
// when the bus being accessed is *not* across a PPB.
|
|
//
|
|
|
|
if (BusData->BusIsAcrossPPB == FALSE) {
|
|
BusNumber = 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Initialize PciAddr for a PCI type 1 configuration cycle
|
|
//
|
|
|
|
pPciAddr->u.AsULONG = McDevid.all << 24;
|
|
pPciAddr->u.bits1.BusNumber = BusNumber;
|
|
pPciAddr->u.bits1.DeviceNumber = Slot.u.bits.DeviceNumber;
|
|
pPciAddr->u.bits1.FunctionNumber = Slot.u.bits.FunctionNumber;
|
|
pPciAddr->u.bits1.Reserved1 = PciConfigType1; // don't care!
|
|
|
|
|
|
return;
|
|
}
|