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

📄 hal_pci.c

📁 epson公司的一个关于s1d13706的低层驱动程序
💻 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 + -