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.
 
 
 
 
 
 

427 lines
12 KiB

/*++
Copyright (c) 1996-2001 Microsoft Corporation
Module Name:
init8x.c
Abstract:
This module contains the initialization code for AMDAGP8X.SYS.
Author:
John Vert (jvert) 10/21/1997
Revision History:
--*/
/*
******************************************************************************
* Archive File : $Archive: /Drivers/OS/Hammer/AGP/XP/amdagp/Init8x.c $
*
* $History: Init8x.c $
*
*
******************************************************************************
*/
#include "amdagp8x.h"
#define MAX_DEVICES 32
#ifdef DISPLAY
ULONG ErrorControl = 2;
#else
ULONG ErrorControl = 0;
#endif
ULONG VendorID = 0;
ULONG DeviceID = 0;
ULONG AgpLokarSlotID = 0;
ULONG AgpHammerSlotID = 0;
ULONG_PTR OutPostBase;
ULONG AgpExtensionSize = sizeof(AGP_AMD_EXTENSION);
//
// Function Name: DisplayStatus()
//
// Description:
// This routine displays the status value in the Post Display.
//
// Parameter:
// StatusValue - Value to display.
//
// Return: None.
//
void
DisplayStatus( IN UCHAR StatusValue )
{
UCHAR to80;
if (ErrorControl) {
to80 = StatusValue & 0xFF;
WRITE_PORT_UCHAR((PUCHAR)OutPostBase, to80);
}
}
//
// Function Name: FindLokar()
//
// Description:
// This routine locates which device number is assigned to Lokar.
//
// Parameter:
// SlotID - Returned slot ID for Lokar.
//
// Return: None.
//
void
FindLokar( OUT PULONG SlotID )
{
PCI_SLOT_NUMBER SlotNum;
ULONG dev, TargetID;
SlotNum.u.AsULONG = 0;
*SlotID = 0;
for (dev = 0; dev < MAX_DEVICES; dev++)
{
SlotNum.u.bits.DeviceNumber = dev;
ReadAMDConfig(SlotNum.u.AsULONG, &TargetID, 0, sizeof(TargetID));
if (((TargetID & DEVICEID_MASK) >> 16) == DEVICE_LOKAR)
{
*SlotID = SlotNum.u.AsULONG;
AGPLOG(AGP_NOISE, ("FindLokar - SlotID=%x\n", *SlotID));
break;
}
}
}
//
// Function Name: FindHammer()
//
// Description:
// This routine locates which device number is assigned to Hammer.
//
// Parameter:
// SlotID - Returned slot ID for Hammer.
//
// Return: None.
//
void
FindHammer( OUT PULONG SlotID )
{
PCI_SLOT_NUMBER SlotNum;
ULONG dev, TargetID;
SlotNum.u.AsULONG = 0;
SlotNum.u.bits.FunctionNumber = 3;
*SlotID = 0;
for (dev = 0; dev < MAX_DEVICES; dev++)
{
SlotNum.u.bits.DeviceNumber = dev;
ReadAMDConfig(SlotNum.u.AsULONG, &TargetID, 0, sizeof(TargetID));
if (((TargetID & DEVICEID_MASK) >> 16) == DEVICE_HAMMER)
{
*SlotID = SlotNum.u.AsULONG;
AGPLOG(AGP_NOISE, ("FindHammer - SlotID=%x\n", *SlotID));
break;
}
}
}
//
// Function Name: AgpInitializeTarget()
//
// Description:
// Entrypoint for target initialization. This is called first.
//
// Parameters:
// AgpExtension - Supplies the AGP extension.
//
// Return:
// STATUS_SUCCESS on success, otherwise STATUS_UNSUCCESSFUL.
//
NTSTATUS
AgpInitializeTarget( IN PVOID AgpExtension )
{
ULONG TargetId = 0;
UNICODE_STRING tempString;
unsigned short tempBuffer[20];
PAGP_AMD_EXTENSION Extension = AgpExtension;
//
// This driver is not MP safe! If there is more than one processor
// we simply fail start
//
if (KeNumberProcessors > 1) {
return STATUS_NOT_SUPPORTED;
}
//
// Register OutPostCode port, if specified by ErrorControl
//
if (ErrorControl) {
PHYSICAL_ADDRESS PortAddress;
PHYSICAL_ADDRESS MappedAddress;
ULONG MemType = 1;
PortAddress.LowPart = 0x80;
PortAddress.HighPart = 0;
HalTranslateBusAddress(Isa, 0, PortAddress, &MemType, &MappedAddress);
if (MemType == 0)
OutPostBase = (ULONG_PTR)MmMapIoSpace(MappedAddress, 1, FALSE);
else
OutPostBase = (ULONG_PTR)MappedAddress.LowPart;
}
if (ErrorControl == 2)
AgpLogLevel = AGP_NOISE; // Log everything
//
// Make sure we are really loaded only on AMD Hammer / Lokar
//
FindLokar(&AgpLokarSlotID);
FindHammer(&AgpHammerSlotID);
ReadAMDConfig(AgpLokarSlotID, &TargetId, 0, sizeof(TargetId));
VendorID = TargetId & VENDORID_MASK;
DeviceID = (TargetId & DEVICEID_MASK) >> 16;
ASSERT(VendorID == VENDOR_AMD);
if (VendorID != VENDOR_AMD || DeviceID != DEVICE_LOKAR) {
AGPLOG(AGP_CRITICAL,
("AGPAMD - AgpInitializeTarget called for platform %08lx which is not an AMD!\n",
VendorID));
return(STATUS_UNSUCCESSFUL);
}
//
// Initialize our chipset-specific extension
//
Extension->ApertureStart.QuadPart = 0;
Extension->ApertureLength = 0;
Extension->Gart = NULL;
Extension->GartLength = 0;
Extension->GartPhysical.QuadPart = 0;
Extension->SpecialTarget = 0;
DisplayStatus(0x10);
return(STATUS_SUCCESS);
}
//
// Function Name: AgpInitializeMaster()
//
// 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.
//
// Parameters:
// AgpExtension - Supplies the AGP extension.
// AgpCapabilities - Returns the capabilities of this AGP device.
//
// Return:
// STATUS_SUCCESS on success, otherwise NTSTATUS.
//
NTSTATUS
AgpInitializeMaster( IN PVOID AgpExtension,
OUT ULONG *AgpCapabilities )
{
NTSTATUS Status;
PCI_AGP_CAPABILITY MasterCap;
PCI_AGP_CAPABILITY TargetCap;
PAGP_AMD_EXTENSION Extension = AgpExtension;
ULONG SBAEnable = 0;
ULONG FWEnable = 0;
ULONG FourGBEnable = 0;
ULONG AperturePointer;
ULONG DataRate;
ULONG IrongateRev = 0;
BOOLEAN ReverseInit;
#if DBG
PCI_AGP_CAPABILITY CurrentCap;
#endif
//
// Indicate that we can map memory through the GART aperture
//
*AgpCapabilities = AGP_CAPABILITIES_MAP_PHYSICAL;
//
// Get the master and target AGP capabilities
//
Status = AgpLibGetMasterCapability(AgpExtension, &MasterCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("AGPAMDInitializeDevice - AgpLibGetMasterCapability failed %08lx\n",
Status));
DisplayStatus(0xA0);
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,
("AGPAMDInitializeDevice - AgpLibGetMasterCapability returned no valid transfer rate\n"));
return(STATUS_INVALID_DEVICE_REQUEST);
}
Status = AgpLibGetPciDeviceCapability(AGP_GART_BUS_ID, AgpLokarSlotID, &TargetCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("AGPAMDInitializeDevice - AgpLibGetPciDeviceCapability failed %08lx\n",
Status));
DisplayStatus(0xA1);
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);
}
//
// 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.
//
FWEnable = (TargetCap.AGPStatus.FastWrite &
MasterCap.AGPStatus.FastWrite);
//
// Enable 4GB addressing if aperture pointer is 64-bit.
//
ReadAMDConfig(AgpLokarSlotID, &AperturePointer, APBASE_OFFSET, sizeof(AperturePointer));
if (AperturePointer & APBASE_64BIT_MASK)
FourGBEnable = 1;
//
// Enable the Master first.
//
ReverseInit =
(Extension->SpecialTarget & AGP_FLAG_REVERSE_INITIALIZATION) ==
AGP_FLAG_REVERSE_INITIALIZATION;
if (ReverseInit) {
MasterCap.AGPCommand.Rate = DataRate;
MasterCap.AGPCommand.AGPEnable = 1;
MasterCap.AGPCommand.SBAEnable = SBAEnable;
MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
MasterCap.AGPCommand.FastWriteEnable = FWEnable;
MasterCap.AGPCommand.FourGBEnable = FourGBEnable;
Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("AGPAMDInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
&MasterCap,
Status));
DisplayStatus(0xA3);
}else {
AGPLOG(AGP_NOISE,
("AgpInitializeMaster - DataRate=%d, SBAEnable=%d\n",
DataRate,
SBAEnable));
}
}
//
// Now enable the Target.
//
TargetCap.AGPCommand.Rate = DataRate;
TargetCap.AGPCommand.AGPEnable = 1;
TargetCap.AGPCommand.SBAEnable = SBAEnable;
TargetCap.AGPCommand.FastWriteEnable = FWEnable;
TargetCap.AGPCommand.FourGBEnable = FourGBEnable;
Status = AgpLibSetPciDeviceCapability(AGP_GART_BUS_ID, AgpLokarSlotID, &TargetCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("AGPAMDInitializeDevice - AgpLibSetPciDeviceCapability %08lx for target failed %08lx\n",
&TargetCap,
Status));
DisplayStatus(0xA2);
return(Status);
}
if (!ReverseInit) {
MasterCap.AGPCommand.Rate = DataRate;
MasterCap.AGPCommand.AGPEnable = 1;
MasterCap.AGPCommand.SBAEnable = SBAEnable;
MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
MasterCap.AGPCommand.FastWriteEnable = FWEnable;
MasterCap.AGPCommand.FourGBEnable = FourGBEnable;
Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("AGPAMDInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
&MasterCap,
Status));
DisplayStatus(0xA3);
}else {
AGPLOG(AGP_NOISE,
("AgpInitializeMaster - DataRate=%d, SBAEnable=%d\n",
DataRate,
SBAEnable));
}
}
#ifdef DEBUG2
//
// Read them back, see if it worked
//
Status = AgpLibGetMasterCapability(AgpExtension, &CurrentCap);
AGP_ASSERT(NT_SUCCESS(Status));
AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &MasterCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
Status = AgpLibGetPciDeviceCapability(AGP_GART_BUS_ID, AgpLokarSlotID, &CurrentCap);
AGP_ASSERT(NT_SUCCESS(Status));
AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &TargetCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
#endif
DisplayStatus(0x20);
return(Status);
}