⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmhal.c

📁 PNX系列设备驱动 PNX系列设备驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/*---------------------------------------------------------------------------- 
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;;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -