?? tmhal.c
字號:
/*----------------------------------------------------------------------------
COPYRIGHT (c) 1998 by Philips Semiconductors
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED AND COPIED IN
ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH A LICENSE AND WITH THE
INCLUSION OF THE THIS COPY RIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES
OF THIS SOFTWARE MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER
PERSON. THE OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ANY PRIOR NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY Philips Semiconductor.
PHILIPS ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE
ON PLATFORMS OTHER THAN THE ONE ON WHICH THIS SOFTWARE IS FURNISHED.
----------------------------------------------------------------------------*/
//////////////////////////////////////////////////////////////////////////////
// HISTORY
//
// 960510 Tilakraj Roy Created
// 970527 Tilakraj Roy Ported to Windows NT with TMMan V4.0 interfaces
// 970806 Tilakraj Roy Ported to Windows NT with TMMan V5.0 interfaces
//
// 010828 Wim de Haan Changed code to remove compiler warnings:
// line 937 '!=' : signed/unsigned mismatch
// line 669 'halResetDSP' : not all control paths
// return a value
// Moved "HalObject" struct typedef to "platform.h"
// for because it is needed by "osal.c"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDE FILES
//////////////////////////////////////////////////////////////////////////////
#include "wdm.h"
//////////////////////////////////////////////////////////////////////////////
// DRIVER SPECIFIC INCLUDE FILES
//////////////////////////////////////////////////////////////////////////////
#include "tmmanlib.h"
#include "platform.h"
#include "mmio.h"
//////////////////////////////////////////////////////////////////////////////
// MANIFEST CONSTANTS
//////////////////////////////////////////////////////////////////////////////
#define HalFourCC tmmanOBJECTID ( 'H', 'A', 'L', ' ' )
//////////////////////////////////////////////////////////////////////////////
// TYPEDEFS
//////////////////////////////////////////////////////////////////////////////
#define PCI_CONFIG_ADDR_PORT ((PULONG)0xcf8)
#define PCI_CONFIG_DATA_PORT ((PULONG)0xcfc)
typedef struct _PCI_CONFIG_ADDRESS
{
union
{
struct{
ULONG Zeros:2;
ULONG RegisterNumber:6;
ULONG FunctionNumber:3;
ULONG DeviceNumber:5;
ULONG BusNumber:8;
ULONG Reserved:7;
ULONG Enable:1;
}Bits;
ULONG Long;
}u;
} PCI_CONFIG_ADDRESS, *PPCI_CONFIG_ADDRESS;
//////////////////////////////////////////////////////////////////////////////
// PROTOTYPES
//////////////////////////////////////////////////////////////////////////////
void halDumpObject (
UInt32 HalHandle );
VOID halUnmapUserAddress (
PVOID Mdl );
PVOID halMapKernelAddressToUserAddress (
HANDLE PhysicalMemoryHandle,
PVOID KernelModeVirtualAddress,
ULONG Length,
PVOID *MdlPointer );
BOOLEAN halHardwareInterruptHandler (
PKINTERRUPT Interrupt,
PVOID ServiceContext );
VOID halDeferredInterruptHandler (
PKDPC Dpc,
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context );
//////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION
//////////////////////////////////////////////////////////////////////////////
TMStatus halCreate (
Pointer Parameters,
UInt32* HalHandlePointer )
{
TMStatus Status = statusHalInitializationFail;
NTSTATUS NTStatus;
HalObject* Hal;
//ULONG AddressSpace;
ULONG Idx;
DEVICE_DESCRIPTION DeviceDescription;
if ( ( Hal = objectAllocate (
sizeof ( HalObject ),
HalFourCC ) ) == NULL )
{
DPF(0,("tmman:halCreate:objectAllocate:FAIL\n" ));
Status = statusObjectAllocFail;
goto halCreateExit1;
}
Hal->SelfInterrupt = ((halParameters*)Parameters)->PCIIrq;// from Target -> Host
Hal->PeerInterrupt = ((halParameters*)Parameters)->TMIrq;// Host -> Target
Hal->Handler = Null;
Hal->Context = Null;
Hal->Swapping = False; // target running in same endianness
Hal->TMDeviceVendorID = ((halParameters*)Parameters)->TMDeviceVendorID;
Hal->TMSubsystemID = ((halParameters*)Parameters)->TMSubsystemID;
Hal->TMClassRevisionID = ((halParameters*)Parameters)->TMClassRevisionID;
Hal->BridgeDeviceVendorID = ((halParameters*)Parameters)->BridgeDeviceVendorID;
Hal->BridgeSubsystemID = ((halParameters*)Parameters)->BridgeSubsystemID;
Hal->BridgeClassRevisionID = ((halParameters*)Parameters)->BridgeClassRevisionID;
/* BEGIN Platform Specific */
Hal->BusNumber = ((halParameters*)Parameters)->BusNumber;
Hal->SlotNumber = ((halParameters*)Parameters)->SlotNumber;
// global device & driver object
Hal->DeviceObject = ((halParameters*)Parameters)->DeviceObject;
Hal->DriverObject = ((halParameters*)Parameters)->DriverObject;
Hal->DSPNumber = ((halParameters*)Parameters)->DSPNumber;
Hal->MMIOAddrPhysical = ((halParameters*)Parameters)->MMIOAddrPhysical;
Hal->MMIOLength = ((halParameters*)Parameters)->MMIOLength;
Hal->SDRAMAddrPhysical = ((halParameters*)Parameters)->SDRAMAddrPhysical;
Hal->SDRAMLength = ((halParameters*)Parameters)->SDRAMLength;
Hal->Control = ((halParameters*)Parameters)->SharedData;
Hal->SpeculativeLoadFix = ((halParameters*)Parameters)->SpeculativeLoadFix;
Hal->PhysicalDeviceObject = ((halParameters*)Parameters)->PhysicalDeviceObject;
Hal->FunctionalDeviceObject = ((halParameters*)Parameters)->FunctionalDeviceObject;
Hal->StackDeviceObject = ((halParameters*)Parameters)->StackDeviceObject;
// performance counters
Hal->DPCRequested = 0;
Hal->DPCLatency = 0;
Hal->DPCDuration = 0;
Hal->LastInterrupt = 0;
Hal->InterruptInterval = 0;
for ( Idx = 0 ; Idx < constTMMANPCIRegisters ; Idx ++ )
{
Hal->PCIRegisters[Idx] =
((halParameters*)Parameters)->PCIRegisters[Idx];
}
/*
// Map MMIO address space
AddressSpace = 0x0; // request memory (0x1 for io space)
if ( ! HalTranslateBusAddress (
PCIBus,
Hal->BusNumber,
Hal->MMIOAddrPhysical,
&AddressSpace,
&Hal->MMIOAddrTranslated ) )
{
DPF(0,("tmman:halCreate:HalTranslateBusAddress:MMIO:FAIL\n" ));
goto halCreateExit2;
}
*/
if ( ( Hal->MMIOAddrKernel = MmMapIoSpace(
Hal->MMIOAddrPhysical,
Hal->MMIOLength,
FALSE ) ) == NULL )
{
DPF(0,("tmman:halCreate:MmMapIoSpace:MMIO:Phys[0x%x:%x]:Len[0x%x]:FAIL\n",
Hal->MMIOAddrPhysical.HighPart, Hal->MMIOAddrPhysical.LowPart,
Hal->MMIOLength ));
goto halCreateExit2;
}
/*
// Now map in the SDRAM Window
AddressSpace = 0x0; // request memory (0x1 for io space)
if ( ! HalTranslateBusAddress(
PCIBus,
Hal->BusNumber,
Hal->SDRAMAddrPhysical,
&AddressSpace,
&Hal->SDRAMAddrTranslated ) )
{
DPF(0,("tmman:halCreate:HalTranslateBusAddress:SDRAM:FAIL\n" ));
goto halCreateExit3;
}
*/
// Put error handling in here, in case it doesn't work. Note that the translated address is the same as the one
// read directly from the configuration register, so this isn't a complete test yet.
if ( ( Hal->SDRAMAddrKernel = MmMapIoSpace(
Hal->SDRAMAddrPhysical,
Hal->SDRAMLength,
FALSE ) ) == NULL )
{
DPF(0,("tmman:halCreate:MmMapIoSpace:SDRAM:Phys[0x%x:%x]:Len[0x%x]:FAIL\n",
Hal->SDRAMAddrPhysical.HighPart, Hal->SDRAMAddrPhysical.LowPart,
Hal->SDRAMLength ));
goto halCreateExit3;
}
if ( ((halParameters*)Parameters)->BridgeDeviceVendorID ==
( ( constTMMANDECBridgeDeviceID << 16 ) | constTMMANDECBridgeVendorID ) )
{
/*
Modify the physical addresses for SDRAM and MMIO to reflect actual
address on the trimedia. After this point only relocation software
is going to use physical addresses. Host based software is going to
use linear addresses
*/
Hal->MMIOAddrPhysicalBridge = Hal->MMIOAddrPhysical;
Hal->SDRAMAddrPhysicalBridge = Hal->SDRAMAddrPhysical;
Hal->Offset = ((halParameters*)Parameters)->SystemBaseAddress;
Hal->MMIOAddrPhysical.LowPart = ((halParameters*)Parameters)->MMIOBaseAddress;
Hal->SDRAMAddrPhysical.LowPart = ((halParameters*)Parameters)->SDRAMBaseAddress;
}
else
{
Hal->Offset = 0;
}
/* do the interrupt stuff */
// Irql needed for HalGetInterruptVector.
//Irql is type KIRQL, which is UCHAR; InterruptLevel is ULONG.
// According to ddk, this must be set on entry to HalGetInterruptVector.
/*
Hal->Irql = (KIRQL) ((halParameters*)Parameters)->InterruptLevel;
Hal->MappedInterruptVector = HalGetInterruptVector (
PCIBus, // IN INTERFACE_TYPE InterfaceType,
((halParameters*)Parameters)->BusNumber, // IN ULONG BusNumber,
((halParameters*)Parameters)->InterruptLevel, // IN ULONG BusInterruptLevel,
((halParameters*)Parameters)->InterruptVector, // IN ULONG BusInterruptVector,
&Hal->Irql, // OUT PKIRQL Irql,
&Hal->ProcessorEnableMask // OUT PKAFFINITY Affinity
);
*/
NTStatus = IoConnectInterrupt(
&Hal->InterruptObject, // OUT PKINTERRUPT *InterruptObject,
halHardwareInterruptHandler, // IN PKSERVICE_ROUTINE ServiceRoutine,
Hal, // IN PVOID ServiceContext,
NULL, // IN PKSPIN_LOCK SpinLock, /* optional */
((halParameters*)Parameters)->InterruptVector, // IN ULONG Vector,
((halParameters*)Parameters)->InterruptLevel, // IN KIRQL Irql,
((halParameters*)Parameters)->InterruptLevel, // IN KIRQL SynchronizeIrql,
((halParameters*)Parameters)->InterruptMode, // IN KINTERRUPT_MODE InterruptMode,
TRUE, // IN BOOLEAN ShareVector, no interrupt sharing
((halParameters*)Parameters)->InterruptAffinity, // IN KAFFINITY ProcessorEnableMask,
FALSE // IN BOOLEAN FloatingSave
);
if (!NT_SUCCESS ( NTStatus))
{
DPF(0,("tmman:halCreate:IoConnectInterrupt:FAIL[%x]\n", NTStatus ));
goto halCreateExit4;
}
// register the DPC routine for the ISR
IoInitializeDpcRequest ( Hal->FunctionalDeviceObject, halDeferredInterruptHandler );
// allocate the adapter for bus master DMA
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION1;
DeviceDescription.Master = TRUE;
DeviceDescription.ScatterGather = TRUE;;
DeviceDescription.DemandMode = FALSE;
DeviceDescription.AutoInitialize = FALSE;
DeviceDescription.Dma32BitAddresses = TRUE;
DeviceDescription.IgnoreCount = TRUE;
DeviceDescription.Reserved1 = FALSE;
//DeviceDescription.BusNumber = Hal->BusNumber;
DeviceDescription.InterfaceType = PCIBus;
DeviceDescription.DmaWidth = Width32Bits;
DeviceDescription.DmaSpeed = TypeC;
DeviceDescription.MaximumLength = 8 * 1024 * 1024;
//DeviceDescription->DmaChannel;
//DeviceDescription->DmaPort;
Hal->AdapterObject = IoGetDmaAdapter (
Hal->PhysicalDeviceObject,
&DeviceDescription,
&Hal->NumberOfMapRegisters );
if ( Hal->AdapterObject == NULL )
{
DPF(0,("tmman:halCreate:HalGetAdapter:FAIL\n" ));
goto halCreateExit5;
}
/* do this only if we have to run in INTEL MODE */
// assume TM1S+
if ( ( *(PULONG)(Hal->MMIOAddrKernel + BIU_CTL) &
(constTMManBIU_CTL_SE | constTMManBIU_CTL_BO | constTMManBIU_CTL_HE) ) == 0x0 )
{ // virgin biu control
ULONG SwappedBIUControl;
UCHAR TempByte;
SwappedBIUControl =
( constTMManBIU_CTL_SE | constTMManBIU_CTL_BO | constTMManBIU_CTL_HE | constTMManBIU_CTL_SR );
// do a dword swap
TempByte = ((PUCHAR)&SwappedBIUControl)[0];
((PUCHAR)&SwappedBIUControl)[0] = ((PUCHAR)&SwappedBIUControl)[3];
((PUCHAR)&SwappedBIUControl)[3] = TempByte;
TempByte = ((PUCHAR)&SwappedBIUControl)[1];
((PUCHAR)&SwappedBIUControl)[1] = ((PUCHAR)&SwappedBIUControl)[2];
((PUCHAR)&SwappedBIUControl)[2] = TempByte;
*(PULONG)(Hal->MMIOAddrKernel + BIU_CTL) = SwappedBIUControl;
Hal->FirstTimeReset = TRUE;
}
else
Hal->FirstTimeReset = FALSE;
}
// set the cache details every time this function is called
*(PULONG)(Hal->MMIOAddrKernel + DRAM_LIMIT) = Hal->SDRAMAddrPhysical.LowPart + Hal->SDRAMLength;
//this->MMIO.pCache->dwDRAMCacheableLimit = this->dwSDRAMPhys;
*(PULONG)(Hal->MMIOAddrKernel + DRAM_CACHEABLE_LIMIT) = Hal->SDRAMAddrPhysical.LowPart + Hal->SDRAMLength;
*(PULONG)(Hal->MMIOAddrKernel + ICLEAR) = (ULONG)(0x0);
*(PULONG)(Hal->MMIOAddrKernel + IMASK) = (ULONG)(~0x0);
Status = statusSuccess;
*HalHandlePointer = (UInt32)Hal;
halDumpObject ( (UInt32)Hal );
return Status;
/* SEH code */
halCreateExit5:
IoDisconnectInterrupt ( Hal->InterruptObject );
halCreateExit4:
MmUnmapIoSpace ( Hal->SDRAMAddrKernel, Hal->SDRAMLength );
halCreateExit3:
MmUnmapIoSpace ( Hal->MMIOAddrKernel, Hal->MMIOLength );
halCreateExit2:
objectFree ( Hal );
halCreateExit1:
return Status;
}
TMStatus halDestroy (
UInt32 HalHandle )
{
HalObject* Hal = (HalObject*)HalHandle;
if ( objectValidate ( Hal, HalFourCC ) != True )
{
DPF(0,("tmman:halDestroy:objectValidate:FAIL\n" ));
return statusInvalidHandle;
}
IoDisconnectInterrupt ( Hal->InterruptObject );
MmUnmapIoSpace ( Hal->SDRAMAddrKernel, Hal->SDRAMLength );
MmUnmapIoSpace ( Hal->MMIOAddrKernel, Hal->MMIOLength );
objectFree ( Hal );
return statusSuccess;;
}
TMStatus halReset (
UInt32 HalHandle )
{
HalObject* Hal = (HalObject*)HalHandle;
if ( objectValidate ( Hal, HalFourCC ) != True )
{
DPF(0,("tmman:halReset:objectValidate:FAIL\n" ));
return statusInvalidHandle;
}
Hal->Control->HostInterruptSpinLock =
halAccess32 ( HalHandle, False );
Hal->Control->TargetInterruptSpinLock =
halAccess32 ( HalHandle, False );
return statusSuccess;
}
TMStatus halSetPeerVersion (
UInt32 HalHandle,
UInt32 MajorVersion,
UInt32 MinorVersion )
{
HalObject* Hal = (HalObject*)HalHandle;
if ( objectValidate ( Hal, HalFourCC ) != True )
{
DPF(0,("tmman:halSetPeerVersion:objectValidate:FAIL\n" ));
return statusInvalidHandle;
}
Hal->PeerMajorVersion = MajorVersion;
Hal->PeerMinorVersion = MinorVersion;
return statusSuccess;
}
TMStatus halGetPeerVersion (
UInt32 HalHandle,
UInt32* MajorVersionPtr,
UInt32* MinorVersionPtr )
{
HalObject* Hal = (HalObject*)HalHandle;
if ( objectValidate ( Hal, HalFourCC ) != True )
{
DPF(0,("tmman:halGetPeerVersion:objectValidate:FAIL\n" ));
return statusInvalidHandle;
}
*MajorVersionPtr = Hal->PeerMajorVersion;
*MinorVersionPtr = Hal->PeerMinorVersion;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -