📄 hal_platform.c
字号:
//===========================================================================
// HAL_PLATFORM.C
//---------------------------------------------------------------------------
//
// Copyright (c) 2003 Epson Research and Development, Inc.
// All Rights Reserved.
//
//===========================================================================
#include <stdlib.h>
#include "hal_private.h"
#include "hal_platform.h"
#include "pcibridge.h"
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static HANDLE ghHalMutex; // Process synchronization mutex handle
#endif
#define DEFAULT_BLOCK_SIZE 0x00400000UL // Total size of PCI virtual memory block
static void ExitHandler( void );
static int Pci2Hal( Boolean fPCIResult );
static UInt32 Get13xxxBaseAddress( Boolean fEnable );
static int AllocateSharedMemory( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize );
static void FreeSharedMemory( void );
//----------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDelayUS()
//----------------------------------------------------------------------------
Boolean halpDelayUS( UInt32 microseconds )
{
#ifdef _WIN32
static UInt32 NsPerTick = 0;
__int64 nanoseconds = microseconds*1000i64;
__int64 Count, Target;
// Init the ns/Tick constant if this is the first time here.
if ( !NsPerTick )
{
if ( QueryPerformanceFrequency((PLARGE_INTEGER)&Count) )
NsPerTick = (UInt32)(1000000000i64/Count);
else
return FALSE;
}
// Exit OK if requested delay is too short.
if ( nanoseconds < NsPerTick )
return TRUE;
// Get the starting initial counter value now.
if ( !QueryPerformanceCounter((PLARGE_INTEGER)&Target) )
return FALSE;
// Calculate the terminal count of ticks required for requested delay.
Target += nanoseconds/NsPerTick;
// Loop until the counter exceeds the number of ticks in the requested delay.
do
{
QueryPerformanceCounter( (PLARGE_INTEGER)&Count );
} while ( Count < Target );
return TRUE;
#elif defined(MV850E)
volatile UInt32 i;
volatile UInt32 adjust;
adjust = (microseconds * 10L) / 18L;
for (i = 0; i < adjust; ++i)
continue;
return TRUE;
#else //_WIN32
#pragma message(">>>>> Function halpDelayUS() must be written for this platform. <<<<<")
return FALSE;
#endif
}
//---------------------------------------------------------------------------
// PLATFORM FUNCTION: halpMapPhysicalToVirtual()
//---------------------------------------------------------------------------
int halpMapPhysicalToVirtual( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize )
{
static Boolean fExitHandler = FALSE;
// Always register the atexit routine at least once, so any allocated
// resources are guaranteed to be released and freed.
if ( !fExitHandler )
{
fExitHandler = TRUE;
atexit( ExitHandler );
}
#if defined(_WIN32)
return Pci2Hal( pcibMapAddress(PhysicalAddr,pVirtualAddr,pBlockSize) );
#else
// On non-Windows system, a physical address of zero is bad karma.
if ( PhysicalAddr == 0 )
return ERR_FAILED;
if ( pVirtualAddr )
*pVirtualAddr = PhysicalAddr;
if ( pBlockSize )
*pBlockSize = DEFAULT_BLOCK_SIZE;
return ERR_NONE;
#endif
}
//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpAddInterruptRegister()
//---------------------------------------------------------------------------------------
int halpAddInterruptRegister( UInt32 EnableReg, UInt32 StatusReg, UInt32 BitMask, UInt32 AccessSize, Boolean fRawStatus )
{
#ifdef _WIN32
EnableReg += HalInfo.dwRegisterOffset;
StatusReg += HalInfo.dwRegisterOffset;
return Pci2Hal( pcibAddInterruptRegister(EnableReg,StatusReg,BitMask,AccessSize,fRawStatus) );
#else
// On non-Windows system, new code to handle interrupts must be written.
#pragma message(">>>>> halpAddInterruptRegister() must be written for this platform. <<<<<")
return ERR_IRQ_FAILURE;
#endif
}
//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpSetISRCallback()
//---------------------------------------------------------------------------------------
int halpSetISRCallback( void(*pISRCallback)(void) )
{
#ifdef _WIN32
return Pci2Hal( pcibHookInterrupt(pISRCallback) );
#else
// On non-Windows system, new code to handle interrupts must be written.
#pragma message(">>>>> halpSetISRCallback() must be written for this platform. <<<<<")
return ERR_IRQ_FAILURE;
#endif
}
//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDirectRead()
//---------------------------------------------------------------------------------------
UInt32 halpDirectRead( int Size, UInt32 Address )
{
if ( Size == sizeof(UInt8) )
{
return *(pUInt8)Address;
}
else if ( Size == sizeof(UInt16) )
{
return *(pUInt16)Address;
}
else if ( Size == sizeof(UInt32) )
{
return *(pUInt32)Address;
}
return 0;
}
//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDirectWrite()
//---------------------------------------------------------------------------------------
void halpDirectWrite( int Size, UInt32 Address, UInt32 Value, UInt32 Count )
{
if ( Count )
{
if ( Size == sizeof(UInt8) )
{
pUInt8 pWrite = (pUInt8)Address;
do
*pWrite++ = (UInt8)Value;
while ( --Count );
}
else if ( Size == sizeof(UInt16) )
{
pUInt16 pWrite = (pUInt16)Address;
do
*pWrite++ = (UInt16)Value;
while ( --Count );
}
else if ( Size == sizeof(UInt32) )
{
pUInt32 pWrite = (pUInt32)Address;
do
*pWrite++ = Value;
while ( --Count );
}
}
}
//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDirectReadData()
//---------------------------------------------------------------------------------------
void halpDirectReadData( int Size, UInt32 Address, void* pData, UInt32 Count )
{
if ( Count && pData )
{
if ( Size == sizeof(UInt8) )
{
pUInt8 pRead = (pUInt8)Address;
pUInt8 pWrite = pData;
do
*pWrite++ = *pRead++;
while ( --Count );
}
else if ( Size == sizeof(UInt16) )
{
pUInt16 pRead = (pUInt16)Address;
pUInt16 pWrite = pData;
do
*pWrite++ = *pRead++;
while ( --Count );
}
else if ( Size == sizeof(UInt32) )
{
pUInt32 pRead = (pUInt32)Address;
pUInt32 pWrite = pData;
do
*pWrite++ = *pRead++;
while ( --Count );
}
}
}
//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDirectWriteData()
//---------------------------------------------------------------------------------------
void halpDirectWriteData( int Size, UInt32 Address, const void* pData, UInt32 Count )
{
if ( Count && pData )
{
if ( Size == sizeof(UInt8) )
{
const UInt8* pRead = pData;
pUInt8 pWrite = (pUInt8)Address;
do
*pWrite++ = *pRead++;
while ( --Count );
}
else if ( Size == sizeof(UInt16) )
{
const UInt16* pRead = pData;
pUInt16 pWrite = (pUInt16)Address;
do
*pWrite++ = *pRead++;
while ( --Count );
}
else if ( Size == sizeof(UInt32) )
{
const UInt32* pRead = pData;
pUInt32 pWrite = (pUInt32)Address;
do
*pWrite++ = *pRead++;
while ( --Count );
}
}
}
//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halSetProcessExclusivity()
//---------------------------------------------------------------------------------------
void halSetProcessExclusivity( Boolean fExclusive )
{
}
//---------------------------------------------------------------------------
// PRIVATE FUNCTION: ExitHandler() - Free up resources at exit time.
//---------------------------------------------------------------------------
static void ExitHandler( void )
{
#if defined(_WIN32)
pcibUnmapAddress();
if ( ghHalMutex )
CloseHandle( ghHalMutex ), ghHalMutex = NULL;
#endif
}
#ifdef _WIN32
//---------------------------------------------------------------------------
// PRIVATE FUNCTION: Pci2Hal() - Map PCI to HAL return code. >>>WIN32 ONLY<<<
//---------------------------------------------------------------------------
static int Pci2Hal( Boolean fPCIResult )
{
int Result = ERR_NONE;
if ( !fPCIResult )
{
switch ( pcibGetLastError() )
{
case PCIE_ERR_ADAPTER_NOT_FOUND: Result = ERR_PCI_ADAPTER_NOT_FOUND; break;
case PCIB_ERR_DRIVER_NOT_FOUND: Result = ERR_PCI_DRIVER_NOT_FOUND; break;
case PCIB_ERR_IRQ_FAILURE: Result = ERR_IRQ_FAILURE; break;
case PCIB_ERR_ADAPTER_NOT_MAPPED: Result = ERR_NOT_ACQUIRED; break;
default: Result = ERR_FAILED; break;
}
}
return Result;
}
#endif //_WIN32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -