📄 pci.c
字号:
//===========================================================================
// PCI.C
// (Tabs set to every 4)
//---------------------------------------------------------------------------
// Copyright (c) 2002, 2003 Epson Research and Development, Inc.
// All Rights Reserved.
//===========================================================================
#include <windows.h>
#include <winioctl.h>
#include "pcibridge.h"
#include "s1d_ioctl.h"
static int gLastError; // PCIBridge last error code
static HANDLE ghPCIDriver; // Handle to PCI driver
static UInt32 gPCIAddress; // Pointer to PCI memory
static ISR_STRUCT gISRInfo; // Interrupt Service Routine info passed to PCI driver
static DWORD ghISRId; // Handle to driver-returned ISR ID (0-31)
static PISR_CALLBACK gpISRCallback; // Application supplied callback function
static Boolean gfISRHooked; // True if device driver has hooked ISR
static void UnhookInterrupt( void );
static Boolean DispatchPCIInterrupt( LPVOID hISREvent );
static int Pci2Hal( Boolean fPCIResult );
//===========================================================================
// PRIVATE GLOBAL VARIABLES (local to HAL only)
//===========================================================================
#define HAL_STRUCT_NAME HalInfo
typedef struct tagDataStruct
{
const char *pszHALRevision; // Full HAL revision string, in SourceSafe format.
const char *pszLIBRevision; // Full LIB revision string, in SourceSafe format.
const char *pszCopyright; // Epson Copyright text
UInt32 BaseAddress; // HAL acquired base address (virtual)
UInt32 RegisterAddress; // HAL acquired register address (virtual)
UInt32 MemoryAddress; // HAL acquired memory address (virtual)
UInt32 BlockSize; // HAL acquired memory block size (bytes)
int nErrorCode; // HAL error code value
Boolean fDebugRegWrites; // True if debugging all register writes
Boolean fDebugHalDelay; // True if debugging HAL delays
} DATA_STRUCT,*PDATA_STRUCT;
static DATA_STRUCT gHD;
// CRITICAL: The messages in this array MUST correspond to the error codes contained in the HAL.H enumeration.
enum
{
ERR_NONE = 0, // No error, call was successful.
ERR_PCI_DRIVER_NOT_FOUND, // The file SED13xx.VxD was not found/loaded.
ERR_PCI_ADAPTER_NOT_FOUND, // The VxD was unable to locate the LCD controller.
ERR_NOT_ACQUIRED, // The controller has not been acquired.
ERR_IRQ_FAILURE, // The interrupt handler failed.
ERR_FAILED // Catch-all error condition.
};
static const char * const gapszErrMsg[ERR_FAILED + 1] =
{
"There was no error detected", // ERR_NONE
"Unable to find/load the S1D13xxx driver", // ERR_PCI_DRIVER_NOT_FOUND
"Unable to locate an S1D13xxx controller", // ERR_PCI_ADAPTER_NOT_FOUND
"The controller has not been acquired", // ERR_NOT_ACQUIRED
"IRQ interrupt handler failure", // ERR_IRQ_FAILURE
"An unspecified error occured" // ERR_FAILED
};
const DATA_STRUCT* const gpHalData = &gHD;
int halpMapPhysicalToVirtual( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize );
//---------------------------------------------------------------------------
// FUNCTION: halAcquireController()
//
// DESCRIPTION:
// This is the discovery portion of the the start-up sequence.
// On the Intel platform, halAcquireController() initiates the link
// between the application and the hardware by attempting to load
// S1D13xxx.VxD. If the driver is loaded successfully then a call
// is made to the VxD to determine the presence and the address
// of the S1D13700. On all other platforms, this routine takes
// the register and display memory addresses provided by 13700CFG.
//
// This routine MUST be called before any other call to the HAL is made!
// (i.e. halInitController)
//
// Applications can call this routine only to obtain pointers to the
// registers and display memory and from there take over all access
// to the S1D13700.
//
// PARAMETERS:
// pMem - Pointer to receive the address of the first byte of display
// memory.
// pReg - Pointer to receive the address of the first byte of register
// space.
//
// RETURNS:
// TRUE if the routine is able to locate an S1D13700.
// *pMem will be the address of the first byte of display memory.
// *pReg will be the address of the first 13700 control register.
// FALSE if an S1D13700 is not located.
// If additional error information is required call
// halGetLastError().
//
// MODIFIES:
// This routine does not modify any register contents.
//---------------------------------------------------------------------------
int AcquireController( UInt32 * pMem )
{
static Boolean fFirstTime = FALSE;
gHD.nErrorCode = ERR_NONE;
if( gHD.BaseAddress == 0 ) // Only do this once, so we are re-entrant.
{
gHD.nErrorCode = halpMapPhysicalToVirtual( 0, &gHD.BaseAddress, &gHD.BlockSize );
if( gHD.nErrorCode != ERR_NONE )
{
gHD.BaseAddress = 0;
return FALSE;
}
gHD.MemoryAddress = gHD.BaseAddress;
}
if( pMem ) *pMem = gHD.BaseAddress;
return TRUE;
}
//---------------------------------------------------------------------------
// PUBLIC FUNCTION: pcibMapAddress()
//---------------------------------------------------------------------------
int pcibMapAddress( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize )
{
BOOL fRet;
DWORD nReturned;
UInt32 aRetPCI[3];
gLastError = PCIB_ERR_NONE;
// Free and release driver, if one's currently in use. This makes
// this function and halAquireController() fully rentrant so they
// can be called multiple times, if required by the application.
pcibUnmapAddress();
// Determine the operating system we are running under and act accordingly.
if ( GetVersion() < 0x80000000 ) // Open the device using NT semantics.
ghPCIDriver = CreateFile( "\\\\.\\S1D13xxx", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL );
else // Open the device using Win9x semantics.
ghPCIDriver = CreateFile( "\\\\.\\S1D13xxx.VXD", 0, 0, NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL );
// If we have an invalid handle then we couldn't open the driver.
if ( ghPCIDriver != INVALID_HANDLE_VALUE )
{
OVERLAPPED OverLapped;
ZeroMemory( &OverLapped, sizeof(OverLapped) );
if ( PhysicalAddr == 0 ) // Map in a PCI Board
{
char Buffer[32];
int boardnum = 0;
// Check the environment for: S1DBOARD=n
// This is for rare situations where there are multiple PCI boards and a command prompt window
// can be assigned to a particular PCI board using the environment variable.
if ( GetEnvironmentVariable("S1DBOARD",Buffer,sizeof(Buffer)) )
boardnum = atoi( Buffer );
// Get virtual address into our PCI array ([0]=virtual, [1]=physical, [2]=blocksize (future))
fRet = DeviceIoControl( ghPCIDriver, IOCTL_SED_MAP_PCI_BOARD, &boardnum, sizeof(boardnum), aRetPCI, sizeof(aRetPCI), &nReturned, &OverLapped );
gPCIAddress = aRetPCI[0];
}
else // The user insists on a particular physical address
{
aRetPCI[0] = PhysicalAddr;
aRetPCI[1] = ISA_BLOCK_SIZE;
fRet = DeviceIoControl( ghPCIDriver, IOCTL_SED_MAP_PHYSICAL_MEMORY, aRetPCI, sizeof(aRetPCI), &gPCIAddress, sizeof(gPCIAddress), &nReturned, &OverLapped );
}
if ( fRet )
{
if ( pVirtualAddr )
*pVirtualAddr = gPCIAddress;
if ( pBlockSize )
{
if ( nReturned > 2*sizeof(aRetPCI[0]) )
*pBlockSize = aRetPCI[2];
else
*pBlockSize = PCI_BLOCK_SIZE;
}
}
else
{
gPCIAddress = 0;
gLastError = PCIE_ERR_ADAPTER_NOT_FOUND;
}
}
else
{
ghPCIDriver = NULL;
gLastError = PCIB_ERR_DRIVER_NOT_FOUND;
}
return (gLastError == PCIB_ERR_NONE);
}
//---------------------------------------------------------------------------
// PUBLIC FUNCTION: pcibUnmapAddress()
//---------------------------------------------------------------------------
void pcibUnmapAddress( void )
{
DWORD nReturned;
// Free up any active interrupt objects to ensure handles are sync'd with resources.
UnhookInterrupt();
// Only free up these resources, if they are currently allocated and in use.
if ( ghPCIDriver )
{
// We already have a handle to the driver and the memory we wish to free.
// Simply call the driver with the appropriate values to free the our memory.
if ( gPCIAddress )
{
OVERLAPPED OverLapped;
ZeroMemory( &OverLapped, sizeof(OverLapped) );
DeviceIoControl( ghPCIDriver, IOCTL_SED_UNMAP_LINEAR_MEMORY, &gPCIAddress, sizeof(gPCIAddress), NULL, 0, &nReturned, &OverLapped );
gPCIAddress = 0;
}
// Close the handle. This also dynamically UNLOADs the driver under Win9x.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -