📄 hal_pci.c
字号:
/*-------------------------------------------------------------------------
//
// File: hal_pci.c
//
// Copyright (c) 2000, 2001 Epson Research and Development, Inc.
// All Rights Reserved.
//
//-----------------------------------------------------------------------*/
#ifdef INTEL_W32
#include <stdlib.h>
#include <stdio.h>
#endif
#ifdef INTEL_DOS
#include <stdlib.h>
#endif
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
/*-----------------------------------------------------------------------*/
static const char Revision[] = "HAL_PCI.C=$Revision: 11 $";
/*-----------------------------------------------------------------------*/
volatile DWORD _RegLinearAddress;
volatile DWORD _DispLinearAddress;
/*-------------------------------------------------------------------------
//
// _InitPlat()
//
//-----------------------------------------------------------------------*/
int _InitPlat(void)
{
_RegLinearAddress = 0;
_DispLinearAddress = 0;
return ERR_OK;
}
/*-------------------------------------------------------------------------
//
// seGetLinearDisplayAddress()
//
//-----------------------------------------------------------------------*/
DWORD seGetLinearDisplayAddress(void)
{
/*
** INTEL_DOS requires the user to call _WRITEXB(), _READXB() when
** using the linear address. Since these calls are internal to the HAL,
** the application cannot use the linear address for INTEL_DOS platforms.
*/
#ifdef LINEAR_ADDRESSES_SUPPORTED
return _DispLinearAddress;
#else
return 0;
#endif
}
/*-------------------------------------------------------------------------
//
// seGetLinearRegAddress()
//
//-----------------------------------------------------------------------*/
DWORD seGetLinearRegAddress(void)
{
/*
** INTEL_DOS requires the user to call _WRITEXB(), _READXB() when
** using the linear address. Since these calls are internal to the HAL,
** the application cannot use the linear address for INTEL_DOS platforms.
*/
#ifdef LINEAR_ADDRESSES_SUPPORTED
return _RegLinearAddress;
#else
return 0;
#endif
}
/*-------------------------------------------------------------------------
//
// GetPCI_DOSPhysicalAddress()
//
//-----------------------------------------------------------------------*/
#ifdef INTEL_DOS
// Vendor ID is for S5U13706B00B board with PCI bridge card which has EPROM marked with BEMV2.
// Vendor ID should be 14EB
// Device ID should be 0020
#define VENDEV 0x002014EB // device_Id + vendor_Id
#define CONFIG_ADDRESS 0xCF8
#define CONFIG_DATA 0xCFC
static DWORD GetPCI_DOSPhysicalAddress(void)
{
DWORD i,j;
int boardnum,found;
char *libvar;
/* Get the value of the S5UBOARD environment variable.
Check the environment for
S5UBOARD=x
where x is a number 0,1,2,3,4,...
This is for those rare situations, where we have multiple
PCI boards. */
boardnum = 0;
libvar = getenv( "S5UBOARD" );
if (libvar != NULL)
boardnum = atoi(libvar);
for (found = 0, i = 0; i < 32; i++)
{
outportl(CONFIG_ADDRESS,(i<<11) | 0x80000000);
j = inportl(CONFIG_DATA);
if (j == VENDEV)
{
if (found == boardnum)
{
outportl(CONFIG_ADDRESS,(i<<11) | 0x80000000 | (1<<2));
j = inportl(CONFIG_DATA);
outportl(CONFIG_DATA,j | 2);
// read DWREG[5] to get the physical ("base") address
outportl(CONFIG_ADDRESS,(i<<11) | 0x80000000 | (4<<2));
return inportl(CONFIG_DATA);
}
found++;
}
}
return 0;
}
#endif
/*-------------------------------------------------------------------------
//
// _InitLinear()
//
// WARNING: This function is only to be called by seRegisterDevice()
//
//-----------------------------------------------------------------------*/
int _InitLinear(void)
{
#ifdef INTEL_W32
int err;
DWORD addr;
#elif defined(INTEL_DOS)
unsigned long errcode;
DWORD dwRegAddress, dwDispMem;
#endif
DWORD offset, baseAddr;
if (_HalInfo->dwDisplayMemoryAddress > _HalInfo->dwRegisterAddress)
{
baseAddr = _HalInfo->dwRegisterAddress;
offset = _HalInfo->dwDisplayMemoryAddress - _HalInfo->dwRegisterAddress;
}
else if (_HalInfo->dwDisplayMemoryAddress < _HalInfo->dwRegisterAddress)
{
baseAddr = _HalInfo->dwDisplayMemoryAddress;
offset = _HalInfo->dwRegisterAddress - _HalInfo->dwDisplayMemoryAddress;
}
else
{
baseAddr = _HalInfo->dwRegisterAddress;
offset = 0x200000; //for EPSON S5U13706 B00C Board only. The offset between
//reg addr and display mem is 0x200000.
}
#ifdef INTEL_W32
#ifdef DEBUG_SIMULATE_MEMORY
printf("DEBUG: Simulating register and display memory.\n");
err = 0;
addr = (DWORD) malloc(0x400000);
if (addr == 0)
return ERR_FAILED;
else
*(BYTE *) addr = 0x28; // Revision code register
#pragma message(" >>>>> DEBUG: Simulating register and display memory <<<<<")
#else
if ((err = _IntelGetLinAddressW32(baseAddr,&addr)) != 0)
{
switch (err)
{
case 1:
return ERR_PCI_DRIVER_NOT_FOUND;
case 2:
return ERR_PCI_BRIDGE_ADAPTER_NOT_FOUND;
default: // Should never get here
return ERR_FAILED;
}
}
#endif // endif for DEBUG_SIMULATE_MEMORY
atexit(seHalTerminate);
if (_HalInfo->dwDisplayMemoryAddress >= _HalInfo->dwRegisterAddress)
{
_RegLinearAddress = addr;
_DispLinearAddress = addr + offset;
}
else
{
_RegLinearAddress = addr + offset;
_DispLinearAddress = addr;
}
#elif defined(INTEL_DOS)
errcode = _INITXLIB();
if (errcode != 0)
return ERR_FAILED;
/*
* Allocate registers.
* The display buffer is allocated 2M, the registers allocated 1M,
* and the hardware suspend allocated the 1M immediately after the
* register block.
*/
dwRegAddress = _HalInfo->dwRegisterAddress;
dwDispMem = _HalInfo->dwDisplayMemoryAddress;
if ((dwRegAddress == 0) && (dwDispMem == 0))
{
dwRegAddress = GetPCI_DOSPhysicalAddress();
if (dwRegAddress == 0)
return ERR_FAILED;
dwDispMem = dwRegAddress + offset;
}
if (dwDispMem < dwRegAddress)
{
errcode = _MAPIOMEM(dwDispMem, dwRegAddress - dwDispMem + offset,
(DWORD *) &_DispLinearAddress);
_RegLinearAddress = _DispLinearAddress + dwRegAddress - dwDispMem;
}
else
{
errcode = _MAPIOMEM(dwRegAddress, dwDispMem - dwRegAddress + offset,
(DWORD *) &_RegLinearAddress);
_DispLinearAddress = _RegLinearAddress + dwDispMem - dwRegAddress;
}
#ifdef _DEBUG
printf("_InitLinear(): errcode=%ld _RegLinearAddress=%08lX _DispLinearAddress=%08lX\n",
errcode, _RegLinearAddress, _DispLinearAddress);
#endif
if (errcode != 0)
return ERR_FAILED;
#endif
return ERR_OK;
}
/*-------------------------------------------------------------------------
//
// _ExitLinear()
//
//-----------------------------------------------------------------------*/
int _ExitLinear(void)
{
#ifndef LINEAR_ADDRESSES_SUPPORTED
_DEINITXLIB ();
#endif
return ERR_OK;
}
/*-----------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -