|
|
/*++
Copyright (c) 1996, 1997 Microsoft Corporation
Module Name:
init.c
Abstract:
This module contains the initialization code for AGPALi.SYS.
Author:
John Vert (jvert) 10/21/1997
Modified by: Chi-Ming Cheng 06/24/1998 Acer Labs, Inc. Wang-Kai Tsai 08/29/2000 Acer Labs, Inc.
Revision History:
--*/
#include "ALiM1541.h"
ULONG AgpExtensionSize = sizeof(AGPALi_EXTENSION); PAGP_FLUSH_PAGES AgpFlushPages;
NTSTATUS AgpInitializeTarget( IN PVOID AgpExtension ) /*++
Routine Description:
Entrypoint for target initialization. This is called first.
Arguments:
AgpExtension - Supplies the AGP extension
Return Value:
NTSTATUS
--*/
{ ULONG VendorId = 0; PAGPALi_EXTENSION Extension = AgpExtension; UCHAR HidId;
//
// Make sure we are really loaded only on a ALi chipset
//
ReadConfigUlong(AGP_ALi_GART_BUS_ID, AGP_ALi_GART_SLOT_ID, &VendorId, 0); ASSERT((VendorId == AGP_ALi_1541_IDENTIFIER) || (VendorId == AGP_ALi_1621_IDENTIFIER) || (VendorId == AGP_ALi_1631_IDENTIFIER) || (VendorId == AGP_ALi_1632_IDENTIFIER) || (VendorId == AGP_ALi_1641_IDENTIFIER) || (VendorId == AGP_ALi_1644_IDENTIFIER) || (VendorId == AGP_ALi_1646_IDENTIFIER) || (VendorId == AGP_ALi_1647_IDENTIFIER) || (VendorId == AGP_ALi_1651_IDENTIFIER) || (VendorId == AGP_ALi_1671_IDENTIFIER) || (VendorId == AGP_ALi_1672_IDENTIFIER));
//
// Determine which particular chipset we are running on.
//
if (VendorId == AGP_ALi_1541_IDENTIFIER) { Extension->ChipsetType = ALi1541; AgpFlushPages = Agp1541FlushPages; } else if (VendorId == AGP_ALi_1621_IDENTIFIER) { Extension->ChipsetType = ALi1621; ReadConfigUchar(AGP_ALi_GART_BUS_ID, AGP_ALi_GART_SLOT_ID, &HidId, M1621_HIDDEN_REV_ID); switch (HidId) { case 0x31: Extension->ChipsetType = ALi1631; break; case 0x32: Extension->ChipsetType = ALi1632; break; case 0x41: Extension->ChipsetType = ALi1641; break; case 0x43: Extension->ChipsetType = ALi1621; break; default: Extension->ChipsetType = ALi1621; break; } AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1631_IDENTIFIER) { Extension->ChipsetType = ALi1631; AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1632_IDENTIFIER) { Extension->ChipsetType = ALi1632; AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1641_IDENTIFIER) { Extension->ChipsetType = ALi1641; AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1644_IDENTIFIER) { Extension->ChipsetType = ALi1644; AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1646_IDENTIFIER) { Extension->ChipsetType = ALi1646; AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1647_IDENTIFIER) { Extension->ChipsetType = ALi1647; AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1651_IDENTIFIER) { Extension->ChipsetType = ALi1651; AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1671_IDENTIFIER) { Extension->ChipsetType = ALi1671; AgpFlushPages = NULL; } else if (VendorId == AGP_ALi_1672_IDENTIFIER) { Extension->ChipsetType = ALi1672; AgpFlushPages = NULL; } else { AGPLOG(AGP_CRITICAL, ("AGPALi - AgpInitializeTarget called for platform %08lx which is not a ALi chipset!\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;
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.
Arguments:
AgpExtension - Supplies the AGP extension
AgpCapabilities - Returns the capabilities of this AGP device.
Return Value:
STATUS_SUCCESS
--*/
{ NTSTATUS Status; PCI_AGP_CAPABILITY MasterCap; PCI_AGP_CAPABILITY TargetCap; PAGPALi_EXTENSION Extension = AgpExtension; ULONG SBAEnable; ULONG DataRate; 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, ("AGPALiInitializeDevice - 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, ("AGP440InitializeDevice - AgpLibGetMasterCapability returned no valid transfer rate\n")); return(STATUS_INVALID_DEVICE_REQUEST); }
Status = AgpLibGetPciDeviceCapability(0,0,&TargetCap); if (!NT_SUCCESS(Status)) { AGPLOG(AGP_CRITICAL, ("AGPALiInitializeDevice - AgpLibGetPciDeviceCapability 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); }
//
// Enable SBA if both master and target support it.
//
SBAEnable = (TargetCap.AGPStatus.SideBandAddressing & MasterCap.AGPStatus.SideBandAddressing);
//
// Before we enable AGP, apply any workarounds
//
AgpWorkaround(Extension);
//
// 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; Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap); if (!NT_SUCCESS(Status)) { AGPLOG(AGP_CRITICAL, ("AGPALiInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n", &MasterCap, Status)); } }
//
// Now enable the Target.
//
TargetCap.AGPCommand.Rate = DataRate; TargetCap.AGPCommand.AGPEnable = 1; TargetCap.AGPCommand.SBAEnable = SBAEnable; Status = AgpLibSetPciDeviceCapability(0, 0, &TargetCap); if (!NT_SUCCESS(Status)) { AGPLOG(AGP_CRITICAL, ("AGPALiInitializeDevice - AgpLibSetPciDeviceCapability %08lx for target failed %08lx\n", &TargetCap, Status)); return(Status); }
if (!ReverseInit) { MasterCap.AGPCommand.Rate = DataRate; MasterCap.AGPCommand.AGPEnable = 1; MasterCap.AGPCommand.SBAEnable = SBAEnable; MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum; Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap); if (!NT_SUCCESS(Status)) { AGPLOG(AGP_CRITICAL, ("AGPALiInitializeDevice - 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. Loosen the assert to not require an
// exact match.
//
AGP_ASSERT(CurrentCap.AGPCommand.RequestQueueDepth <= MasterCap.AGPCommand.RequestQueueDepth); CurrentCap.AGPCommand.RequestQueueDepth = MasterCap.AGPCommand.RequestQueueDepth; AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &MasterCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
Status = AgpLibGetPciDeviceCapability(0,0,&CurrentCap); AGP_ASSERT(NT_SUCCESS(Status)); AGP_ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &TargetCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
#endif
return(Status); }
|