📄 hal_pci.c
字号:
/*-------------------------------------------------------------------------
//
// File: hal_pci.c
//
// Copyright (c) 1997, 2001 Epson Research and Development, Inc.
// All Rights Reserved.
//
//-----------------------------------------------------------------------*/
#ifdef INTEL_W32
#pragma warning(disable:4001) // Disable the 'single line comment' warning.
#pragma warning(disable:4032) // Disable the 'formal parameter 1 has different type when promoted' warning in conio.h
#include <conio.h>
#include <stdlib.h>
#endif
#ifdef _DEBUG
#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: 21 $";
/*-----------------------------------------------------------------------*/
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 INTEL_DOS
return 0;
#else
return _DispLinearAddress;
#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 INTEL_DOS
return 0;
#else
return _RegLinearAddress;
#endif
}
/*-------------------------------------------------------------------------
//
// GetPCI_DOSPhysicalAddress()
//
//-----------------------------------------------------------------------*/
#ifdef INTEL_DOS
#define VENDEV 0x130010F4 // 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
_RegLinearAddress = _HalInfo->dwRegisterAddress;
_DispLinearAddress = _HalInfo->dwDisplayMemoryAddress;
#ifdef INTEL_W32
if ((err = _IntelGetLinAddressW32(_HalInfo->dwRegisterAddress,&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;
}
}
atexit(seHalTerminate);
_RegLinearAddress = addr;
_DispLinearAddress = addr + 0x200000;
#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 + 0x200000;
}
if (dwDispMem < dwRegAddress)
{
errcode = _MAPIOMEM(dwDispMem, dwRegAddress - dwDispMem + 0x200000L,
(DWORD *) &_DispLinearAddress);
_RegLinearAddress = _DispLinearAddress + dwRegAddress - dwDispMem;
}
else
{
errcode = _MAPIOMEM(dwRegAddress, dwDispMem - dwRegAddress + 0x200000L,
(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)
{
#if defined(INTEL_DOS) && defined(__GNUC__)
_DEINITXLIB ();
#else
/*
* Nothing to do here.
*/
#endif
return ERR_OK;
}
/*-----------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -