Leaked source code of windows server 2003
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.
 
 
 
 
 
 

357 lines
10 KiB

/*++
Copyright (2) 2002 Microsoft Corporation
Module Name:
init.c
Abstract:
This module contains the initialization support routines for the
MS AGP v3 Filter Driver
Author:
Eric F. Nelson (enelson) June 6, 2002
Revision History:
--*/
#include "agp.h"
#include "uagp35.h"
ULONG AgpExtensionSize = sizeof(UAGP35_EXTENSION);
PAGP_FLUSH_PAGES AgpFlushPages = NULL; // Not implemented (yet)
NTSTATUS
AgpInitializeTarget(
IN PVOID AgpExtension
)
/*++
Routine Description:
Entrypoint for target initialization, this is called first
Arguments:
AgpExtension - Supplies our AGP3 extension
Return Value:
STATUS_SUCCESS
--*/
{
ULONG DeviceId;
NTSTATUS Status;
PCI_AGP_CAPABILITY TargetCap;
PUAGP35_EXTENSION Extension = AgpExtension;
//
// Zero/init our AGP3 extension
//
RtlZeroMemory(AgpExtension, sizeof(UAGP35_EXTENSION));
//
// Figure out what type of AGP3 capability our target is
//
Status = AgpLibGetTargetCapability(AgpExtension, &TargetCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("UAGP35TargetInit: AgpLibGetTargetCapability "
"failed %08lx\n"));
return Status;
}
Extension->CapabilityId = TargetCap.Header.CapabilityID;
//
// Make sure the capability is v3!!!
//
if ((TargetCap.Major < 3) ||
((TargetCap.Major == 3) && (TargetCap.Minor < 5))) {
AGPLOG(AGP_CRITICAL,
("UAGP35TargetInit: Capability version (%d) != 3\n",
TargetCap.Major));
return STATUS_NOT_SUPPORTED;
}
//
// Save the vendor and device IDs in case we need to "tweak"
// something for a particular platform
//
AgpLibReadAgpTargetConfig(AgpExtension, &DeviceId, 0, sizeof(DeviceId));
Extension->DeviceId = DeviceId;
return STATUS_SUCCESS;
}
NTSTATUS
AgpInitializeMaster(
IN PVOID AgpExtension,
OUT ULONG *AgpCapabilities
)
/*++
Routine Description:
Entrypoint for master initialization, this is called after target
initialization and should be used to initialize the AGP capabilities
of both master and target
This is also called when the master transitions into the D0 state
Arguments:
AgpExtension - Supplies our AGP3 extension
AgpCapabilities - Returns the capabilities of this AGP device
Return Value:
STATUS_SUCCESS, or an appropriate error status
--*/
{
NTSTATUS Status;
PCI_AGP_CAPABILITY MasterCap;
PCI_AGP_CAPABILITY TargetCap;
ULONG ApertureBase;
PUAGP35_EXTENSION Extension = AgpExtension;
ULONG SBAEnable;
ULONG DataRate;
ULONG FourGBEnable = OFF;
ULONG FastWrite;
BOOLEAN ReverseInit;
#if DBG
PCI_AGP_CAPABILITY CurrentCap;
#endif
//
// Get the master and target AGP capabilities
//
Status = AgpLibGetMasterCapability(AgpExtension, &MasterCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("UAGP35MasterInit: AgpLibGetMasterCapability failed %08lx\n"));
return Status;
}
//
// Some broken cards (Matrox Millenium II "AGP") report no valid
// supported transfer rates. These are not really AGP cards. They
// have an AGP Capabilities structure that reports no capabilities.
//
if (MasterCap.AGPStatus.Rate == 0) {
AGPLOG(AGP_CRITICAL,
("UAGP35MasterInit: AgpLibGetMasterCapability returned "
"no valid transfer rate\n"));
return STATUS_INVALID_DEVICE_REQUEST;
}
Status = AgpLibGetTargetCapability(AgpExtension, &TargetCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("UAGP35MasterInit: AgpLibGetTargetCapability "
"failed %08lx\n"));
return Status;
}
//
// Determine the greatest common denominator for data rate.
//
DataRate = TargetCap.AGPStatus.Rate & MasterCap.AGPStatus.Rate;
AGP_ASSERT(DataRate != 0);
//
// Select the highest common rate
//
if (DataRate & PCI_AGP_RATE_4X) {
DataRate = PCI_AGP_RATE_4X;
} else if (DataRate & PCI_AGP_RATE_2X) {
DataRate = PCI_AGP_RATE_2X;
} else if (DataRate & PCI_AGP_RATE_1X) {
DataRate = PCI_AGP_RATE_1X;
}
//
// Previously a call was made to change the rate (successfully),
// use this rate again now
//
if (Extension->SpecialTarget & AGP_FLAG_SPECIAL_RESERVE) {
DataRate = (ULONG)((Extension->SpecialTarget &
AGP_FLAG_SPECIAL_RESERVE) >>
AGP_FLAG_SET_RATE_SHIFT);
//
// If we're in AGP3 mode, and our rate was successfully
// programmed, then we must convert into AGP2 rate bits
//
if (TargetCap.AGPStatus.Agp3Mode == ON) {
ASSERT(MasterCap.AGPStatus.Agp3Mode == ON);
ASSERT((DataRate == 8) || (DataRate == PCI_AGP_RATE_4X));
DataRate >>= 2;
}
}
//
// Enable SBA if both master and target support it
//
SBAEnable = TargetCap.AGPStatus.SideBandAddressing &
MasterCap.AGPStatus.SideBandAddressing;
//
// Enable FastWrite if both master and target support it
//
FastWrite = TargetCap.AGPStatus.FastWrite &
MasterCap.AGPStatus.FastWrite;
//
// Enable 4GB addressing if aperture is 64-bit
//
AgpLibReadAgpTargetConfig(AgpExtension,
&ApertureBase,
APERTURE_BASE,
sizeof(ApertureBase));
if (ApertureBase & APERTURE_BASE64_MASK) {
FourGBEnable = ON;
Extension->FourGBEnable = TRUE;
}
//
// Indicate whether we can map memory through the GART aperture
//
*AgpCapabilities = (TargetCap.AGPStatus.HostTransDisable) ? 0:
AGP_CAPABILITIES_MAP_PHYSICAL;
MasterCap.AGPCommand.Rate = DataRate;
TargetCap.AGPCommand.Rate = DataRate;
MasterCap.AGPCommand.AGPEnable = ON;
TargetCap.AGPCommand.AGPEnable = ON;
MasterCap.AGPCommand.SBAEnable = SBAEnable;
TargetCap.AGPCommand.SBAEnable = SBAEnable;
MasterCap.AGPCommand.FastWriteEnable = FastWrite;
TargetCap.AGPCommand.FastWriteEnable = FastWrite;
MasterCap.AGPCommand.FourGBEnable = FourGBEnable;
TargetCap.AGPCommand.FourGBEnable = FourGBEnable;
MasterCap.AGPCommand.RequestQueueDepth =
TargetCap.AGPStatus.RequestQueueDepthMaximum;
MasterCap.AGPCommand.AsyncReqSize =
TargetCap.AGPStatus.AsyncRequestSize;
//
// Patch rate for early rev VIA 8X silicon errata
//
if ((Extension->SpecialTarget & AGP_FLAG_SPECIAL_VIA_AGP2_RATE_PATCH) &&
(TargetCap.AGPStatus.Agp3Mode == OFF)) {
switch (DataRate) {
case PCI_AGP_RATE_1X:
case PCI_AGP_RATE_2X:
MasterCap.AGPCommand.Rate = PCI_AGP_RATE_1X;
TargetCap.AGPCommand.Rate = PCI_AGP_RATE_4X;
break;
case PCI_AGP_RATE_4X:
MasterCap.AGPCommand.Rate = PCI_AGP_RATE_4X;
TargetCap.AGPCommand.Rate = PCI_AGP_RATE_1X;
}
AGPLOG(AGP_WARNING,
("UAGP35MasterInit: AGP_FLAG_SPECIAL_VIA_AGP2_RATE_PATCH\n"));
}
//
// Enable the Master first if the reverse init bit is set
//
ReverseInit =
(Extension->SpecialTarget & AGP_FLAG_REVERSE_INITIALIZATION) ==
AGP_FLAG_REVERSE_INITIALIZATION;
if (ReverseInit) {
Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("UAGP35MasterInit: AgpLibSetMasterCapability %08lx "
"failed %08lx\n",
&MasterCap,
Status));
return Status;
}
}
//
// Otherwise enable the Target first
//
Status = AgpLibSetTargetCapability(AgpExtension, &TargetCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("UAGP35MasterInit: AgpLibSetTargetCapability %08lx "
"for target failed %08lx\n",
&TargetCap,
Status));
return Status;
}
if (!ReverseInit) {
Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("UAGP35MasterInit: AgpLibSetMasterCapability %08lx "
"failed %08lx\n",
&MasterCap,
Status));
}
}
#if DBG
//
// Read them back, see if it worked
//
Status = AgpLibGetMasterCapability(AgpExtension, &CurrentCap);
AGP_ASSERT(NT_SUCCESS(Status));
//
// If the target request queue depth is greater than the master will
// allow, it will be trimmed, so loosen the assert to not require an
// exact match
//
// We'll do the same for asynchronous request queue depth too
//
AGP_ASSERT(CurrentCap.AGPCommand.RequestQueueDepth <=
MasterCap.AGPCommand.RequestQueueDepth);
AGP_ASSERT(CurrentCap.AGPCommand.AsyncReqSize <=
MasterCap.AGPCommand.AsyncReqSize);
CurrentCap.AGPCommand.RequestQueueDepth =
MasterCap.AGPCommand.RequestQueueDepth;
CurrentCap.AGPCommand.AsyncReqSize = MasterCap.AGPCommand.AsyncReqSize;
AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand,
&MasterCap.AGPCommand,
sizeof(CurrentCap.AGPCommand)));
AGPLOG(AGP_NOISE,
("UAGP35MasterInit: WroteMasterCmd=%08x, ReadMasterCmd=%08lx\n",
MasterCap.AGPCommand,
CurrentCap.AGPCommand));
Status = AgpLibGetTargetCapability(AgpExtension, &CurrentCap);
AGP_ASSERT(NT_SUCCESS(Status));
AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand,
&TargetCap.AGPCommand,
sizeof(CurrentCap.AGPCommand)));
AGPLOG(AGP_NOISE,
("UAGP35MasterInit: WroteTargetCmd=%08x, ReadTargetCmd=%08lx\n",
TargetCap.AGPCommand,
CurrentCap.AGPCommand));
#endif
return Status;
}