?? tmhal.c
字號(hào):
/*----------------------------------------------------------------------------
COPYRIGHT (c) 1997 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 TR Created
// 979527 TR Ported to Windows NT with TMMan V4.0 interfaces
// 970806 Tilakraj Roy Ported to Windows NT with TMMan V5.0 interfaces
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDE FILES
//////////////////////////////////////////////////////////////////////////////
#include "ntddk.h"
//////////////////////////////////////////////////////////////////////////////
// DRIVER SPECIFIC INCLUDE FILES
//////////////////////////////////////////////////////////////////////////////
#include "tmmanlib.h"
#include "platform.h"
#include "mmio.h"
//////////////////////////////////////////////////////////////////////////////
// MANIFEST CONSTANTS
//////////////////////////////////////////////////////////////////////////////
#define HalFourCC tmmanOBJECTID ( 'H', 'A', 'L', ' ' )
//////////////////////////////////////////////////////////////////////////////
// TYPEDEFS
//////////////////////////////////////////////////////////////////////////////
typedef BOOLEAN ( *HOOKFUNCTION ) ( PVOID Context );
typedef struct tagHalObject
{
GenericObject Object;
ULONG TMDeviceVendorID;
ULONG TMSubsystemID;
ULONG TMClassRevisionID;
ULONG BridgeDeviceVendorID;
ULONG BridgeSubsystemID;
ULONG BridgeClassRevisionID;
ULONG SelfInterrupt; // from Target -> Host
ULONG PeerInterrupt; // Host -> Target
HalInterruptHandler Handler;
Pointer Context;
HalControl* Control;
/* true - target processor is running in different indianess */
/* false - target processor is running in different indianess */
Bool Swapping;
ULONG PeerMajorVersion;
ULONG PeerMinorVersion;
/* BEGIN Platform Specific */
ULONG BusNumber;
PCI_SLOT_NUMBER SlotNumber;
PHYSICAL_ADDRESS MMIOAddrPhysicalBridge;
PHYSICAL_ADDRESS MMIOAddrPhysical;
ULONG MMIOLength;
PHYSICAL_ADDRESS MMIOAddrTranslated;
PUCHAR MMIOAddrKernel;
PHYSICAL_ADDRESS SDRAMAddrPhysicalBridge;
PHYSICAL_ADDRESS SDRAMAddrPhysical;
ULONG SDRAMLength;
PHYSICAL_ADDRESS SDRAMAddrTranslated;
PUCHAR SDRAMAddrKernel;
ULONG MappedInterruptVector;
BOOLEAN FirstTimeReset;
KIRQL Irql;
KAFFINITY ProcessorEnableMask;
PKINTERRUPT InterruptObject;
ULONG DSPNumber;
PDEVICE_OBJECT TMManDeviceObject;
PDEVICE_OBJECT DeviceObject;
PDRIVER_OBJECT DriverObject;
PADAPTER_OBJECT AdapterObject;
ULONG NumberOfMapRegisters;
ULONG SpeculativeLoadFix;
ULONG SDRAMMapCount;
ULONG Offset;
HOOKFUNCTION ISRHookFunction;
PVOID ISRHookContext;
ULONG ISRHookFlags;
HOOKFUNCTION DPCHookFunction;
PVOID DPCHookContext;
ULONG DPCHookFlags;
ULONG PCIRegisters[constTMMANPCIRegisters];
} HalObject;
#define PCI_CONFIG_ADDR_PORT ((PUCHAR)0xcf8)
#define PCI_CONFIG_DATA_PORT ((PUCHAR)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;
}BitField;
ULONG Long;
}u;
} PCI_CONFIG_ADDRESS, *PPCI_CONFIG_ADDRESS;
//////////////////////////////////////////////////////////////////////////////
// PROTOTYPES
//////////////////////////////////////////////////////////////////////////////
void halDumpObject (
UInt32 HalHandle );
VOID halUnmapUserAddress (
PVOID UserModeVirtualAddress );
PVOID halMapKernelAddressToUserAddress (
HANDLE PhysicalMemoryHandle,
PVOID KernelModeVirtualAddress,
ULONG Length );
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, Idx;
DEVICE_DESCRIPTION DeviceDescription;
UNICODE_STRING KernelDeviceNameUnicode;
ANSI_STRING KernelDeviceNameANSI;
CHAR KernelDeviceName[32];
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;
Hal->TMManDeviceObject = ((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->SDRAMMapCount = 0;
Hal->ISRHookFunction = NULL;
Hal->ISRHookContext = NULL;
Hal->ISRHookFlags = 0;
Hal->DPCHookFunction = NULL;
Hal->DPCHookContext = NULL;
Hal->DPCHookFlags = 0;
for ( Idx = 0 ; Idx < constTMMANPCIRegisters ; Idx ++ )
{
Hal->PCIRegisters[Idx] =
((halParameters*)Parameters)->PCIRegisters[Idx];
}
// get a handle to the physical memory for mapping user sections
// create a device object for this physical hardware
strSprintf ( KernelDeviceName, "\\Device\\TriMedia%d",
((halParameters*)Parameters)->DSPNumber );
RtlInitAnsiString ( &KernelDeviceNameANSI, KernelDeviceName );
if ( RtlAnsiStringToUnicodeString(
&KernelDeviceNameUnicode,
&KernelDeviceNameANSI,
TRUE) != STATUS_SUCCESS )
{
DPF(0,("tmman:halCreate:RtlAnsiStringToUnicodeString:FAIL\n" ));
goto halCreateExit2;
}
NTStatus = IoCreateDevice(
Hal->DriverObject,
0,
&KernelDeviceNameUnicode,
FILE_DEVICE_UNKNOWN,
0, // No standard device characteristics
FALSE, // This isn't an exclusive device
&Hal->DeviceObject );
if ( ! NT_SUCCESS(NTStatus) )
{
DPF(0,("tmman:halCreate:IoCreateDevice:FAIL[%x]\n", NTStatus ));
goto halCreateExit3;
}
if ( ( Hal->MMIOAddrKernel = halMapAdapterMemory (
Hal->BusNumber,
Hal->MMIOAddrPhysical,
Hal->MMIOLength) ) == NULL )
{
DPF(0,("tmman:halCreate:halMapAdapterMemory:MMIO:FAIL\n" ));
goto halCreateExit4;
}
if ( TMManGlobal->MapSDRAM )
{
if ( ( Hal->SDRAMAddrKernel = halMapAdapterMemory (
Hal->BusNumber,
Hal->SDRAMAddrPhysical,
Hal->SDRAMLength) ) == NULL )
{
DPF(0,("tmman:halCreate:halMapAdapterMemory:SDRAM:FAIL\n" ));
goto halCreateExit5;
}
}
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 */
Hal->MappedInterruptVector, // IN ULONG Vector,
Hal->Irql, // IN KIRQL Irql,
Hal->Irql, // IN KIRQL SynchronizeIrql,
LevelSensitive, // IN KINTERRUPT_MODE InterruptMode,
TRUE, // IN BOOLEAN ShareVector, no interrupt sharing
Hal->ProcessorEnableMask, // IN KAFFINITY ProcessorEnableMask,
FALSE // IN BOOLEAN FloatingSave
);
if (!NT_SUCCESS ( NTStatus))
{
DPF(0,("tmman:halCreate:IoConnectInterrupt:FAIL[%x]\n", NTStatus ));
goto halCreateExit6;
}
// register the DPC routine for the ISR
IoInitializeDpcRequest ( Hal->DeviceObject, 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 = FALSE;
DeviceDescription.Reserved1 = FALSE;
DeviceDescription.Reserved2 = FALSE;
DeviceDescription.BusNumber = Hal->BusNumber;
DeviceDescription.InterfaceType = PCIBus;
DeviceDescription.DmaWidth = 0;
DeviceDescription.DmaSpeed = 0;
DeviceDescription.DmaChannel = 0;
DeviceDescription.DmaPort = 0;
DeviceDescription.MaximumLength = 8 * 1024 * 1024;
Hal->AdapterObject = HalGetAdapter (
&DeviceDescription,
&Hal->NumberOfMapRegisters );
if ( Hal->AdapterObject == NULL )
{
DPF(0,("tmman:halCreate:HalGetAdapter:FAIL\n" ));
goto halCreateExit7;
}
/* 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);
RtlFreeUnicodeString ( &KernelDeviceNameUnicode );
Status = statusSuccess;
*HalHandlePointer = (UInt32)Hal;
halDumpObject ( (UInt32)Hal );
return Status;
/* SEH code */
halCreateExit7:
IoDisconnectInterrupt ( Hal->InterruptObject );
halCreateExit6:
if ( TMManGlobal->MapSDRAM )
{
halUnmapAdapterMemory ( Hal->SDRAMAddrKernel, Hal->SDRAMLength );
}
halCreateExit5:
halUnmapAdapterMemory ( Hal->MMIOAddrKernel, Hal->MMIOLength );
halCreateExit4:
IoDeleteDevice ( Hal->DeviceObject );
halCreateExit3:
RtlFreeUnicodeString ( &KernelDeviceNameUnicode );
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 );
if ( TMManGlobal->MapSDRAM )
{
halUnmapAdapterMemory ( Hal->SDRAMAddrKernel, Hal->SDRAMLength );
}
halUnmapAdapterMemory ( Hal->MMIOAddrKernel, Hal->MMIOLength );
IoDeleteDevice ( Hal->DeviceObject );
objectFree ( Hal );
return statusSuccess;;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -