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

📄 tmhal.c

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