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

📄 tmhal.c

📁 wince host 和 target PCI驱动程序
💻 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
//	979527  Tilakraj Roy	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 "wdm.h"

//////////////////////////////////////////////////////////////////////////////
//				DRIVER SPECIFIC INCLUDE FILES
//////////////////////////////////////////////////////////////////////////////

#include "tmmanlib.h"
#include "platform.h"
#include "mmio.h"

//////////////////////////////////////////////////////////////////////////////
//				MANIFEST CONSTANTS
//////////////////////////////////////////////////////////////////////////////

#define		HalFourCC		tmmanOBJECTID ( 'H', 'A', 'L', ' ' )

//////////////////////////////////////////////////////////////////////////////
//				TYPEDEFS
//////////////////////////////////////////////////////////////////////////////

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;
	PUCHAR				MMIOAddrKernel;

	PHYSICAL_ADDRESS    SDRAMAddrPhysicalBridge;
    PHYSICAL_ADDRESS    SDRAMAddrPhysical;
    ULONG               SDRAMLength;
	PUCHAR				SDRAMAddrKernel;
	

	ULONG				MappedInterruptVector;

	BOOLEAN				FirstTimeReset;

	PKINTERRUPT			InterruptObject;

	ULONG				DSPNumber;

	PDEVICE_OBJECT		PhysicalDeviceObject;
	PDEVICE_OBJECT		FunctionalDeviceObject;
	PDEVICE_OBJECT		StackDeviceObject;

	PDEVICE_OBJECT		DeviceObject;
	PDRIVER_OBJECT		DriverObject;
	PADAPTER_OBJECT		AdapterObject;

	ULONG				NumberOfMapRegisters;
	ULONG				SpeculativeLoadFix;

	ULONG				SDRAMMapCount;
	ULONG				Offset;

	ULONG				PCIRegisters[constTMMANPCIRegisters];

	// performance counters

	ULONGLONG	DPCRequested;
	ULONGLONG	LastInterrupt;

	// worst case numbers
	ULONG	DPCLatency;
	ULONG	DPCDuration;
	ULONG	InterruptInterval;


}	HalObject;

#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;

⌨️ 快捷键说明

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