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

📄 spci.c

📁 scsi脚本文件(scripts)编程例子
💻 C
字号:
/*--------------------------------------------------*/
/*                                                  */
/* Module SPCI.C                                    */
/*                                                  */
/* PCI access functions for sample code.            */
/*                                                  */
/* Adapted from Symbios Logic                       */
/*    Software Development Kit                      */
/*                                                  */
/* Project: A Programmer's Guide to SCSI            */
/* Copyright (C) 1997, Brian Sawert.                */
/* All rights reserved.                             */
/*                                                  */
/*--------------------------------------------------*/


#include <stdio.h>
#include <stdlib.h>
#include <dos.h>

#include "gen_tool.h"         // generic tools
#include "spci.h"             // PCI definitions
#include "s8xx.h"             // Symbios 8XX definitions

#pragma inline                // enable inline assembly


/*---------- defines and macros ----------*/

/*---------- global variables ----------*/

/*---------- external variables ----------*/

/*---------- local functions ----------*/

/*---------- external functions ----------*/

/*---------- function definitions ----------*/


/*--------------------------------------------------*/
/*                                                  */
/* Routine to get PCI BIOS information.             */
/*                                                  */
/* Usage:   WORD PCI_GetPCIBIOSVersion(             */
/*    pci_bios *ppcibios);                          */
/*                                                  */
/* Parameters:                                      */
/*    ppcibios:      pointer to pci_bios struct     */
/*                                                  */
/* Return value:                                    */
/*    Returns PCI BIOS version number on success,   */
/*    0 if PCI BIOS not found. Fills pci_bios       */
/*    struct on success.                            */
/*                                                  */
/*--------------------------------------------------*/

WORD PCI_GetPCIBIOSVersion(pci_bios *ppcibios)
{
   WORD r_ax, r_bx, r_cx, r_dx;  // register variables
   DWORD r_edx;
   DWORD pci_sig;                // PCI signature
   WORD retval = PCI_NO_BIOS;


   pci_sig = 0x20494350L;        // " ICP" signature

   // call PCI function to check for BIOS
   r_ax = ((PCI_FUNCTION_ID << 8) | PCI_BIOS_PRESENT);

   asm {
      .386
      mov ax, [r_ax]
      int PCI_BIOS_INT
      mov DWORD PTR [r_edx], edx
      mov [r_dx], dx
      mov [r_cx], cx
      mov [r_bx], bx
      mov [r_ax], ax
   }

   if (r_dx == LOWORD(pci_sig)) {
   // PCI BIOS is present

      if (r_cx == HIWORD(pci_sig) &&
         (r_bx & 0xff00) == 0x0100) {
      // PCI BIOS version 1.x
         retval = PCI_BIOS_REV_1X;
      }
      else if (r_edx == pci_sig) {
      // PCI BIOS version 2.x
         retval = PCI_BIOS_REV_2X;
      }
      else {
      // unknown version
         retval = PCI_UNKNOWN_BIOS;
      }

      if (ppcibios != NULL) {
      // fill BIOS info struct
         ppcibios->access = (r_ax & 0xff);
         ppcibios->version = r_bx;
         ppcibios->lastbus = (r_cx & 0xff);
      }
   }

   return retval;
}



/*--------------------------------------------------*/
/*                                                  */
/* Routine to locate PCI device.                    */
/*                                                  */
/* Usage:   int PCI_FindDevice(                     */
/*    pci_device *ppcidevice);                      */
/*                                                  */
/* Parameters:                                      */
/*    ppcidevice:    pointer to pci_device struct   */
/*                                                  */
/* Return value:                                    */
/*    Returns 1 if device found, 0 otherwise.       */
/*    Fills pci_device struct on success.           */
/*                                                  */
/*--------------------------------------------------*/

int PCI_FindDevice(pci_device *ppcidevice)
{
// struct REGPACK regs;
   WORD r_ax, r_bx, r_cx, r_dx, r_si;
   DWORD config;
   int retval = 0;


   // make sure we have a PCI BIOS
      if (PCI_GetPCIBIOSVersion(NULL) != PCI_NO_BIOS) {
   // PCI BIOS is present

      // call PCI function to find device
      r_ax = ((PCI_FUNCTION_ID << 8) |
         (PCI_FIND_DEVICE));

      r_cx = ppcidevice->dev_id;
      r_dx = ppcidevice->vend_id;
      r_si = ppcidevice->dev_index;

      asm {
         .386
         mov ax, [r_ax]
         mov cx, [r_cx]
         mov dx, [r_dx]
         mov si, [r_si]
         int PCI_BIOS_INT
         mov ax, 0
         adc ax, 0
         mov [r_bx], bx
         mov [r_ax], ax

      }

      if (r_ax == 0) {
      // carry bit is clear - call succeeded

         // save device bus number
         ppcidevice->bus_num = ((r_bx & 0xFF00) >> 8);

         // save device number
         ppcidevice->dev_num = (r_bx & 0x00FF);

         // save device function
         ppcidevice->function = (r_bx & 0x0007);

         // get command register
         ppcidevice->command =
            (WORD) PCI_GetConfigRegister(
            ppcidevice, PCI_CONFIG_REG_CMD);

         // get revision ID
         ppcidevice->rev_id =
            (BYTE) PCI_GetConfigRegister(
            ppcidevice, PCI_CONFIG_REG_REVID);

         // get subsystem and vendor ID
         config = PCI_GetConfigRegister(
            ppcidevice, PCI_CONFIG_REG_SUBV);
         ppcidevice->sub_vend_id = (WORD) config;
         ppcidevice->sub_id = (WORD) (config >> 16);

         // get I/O base address
         config = PCI_GetConfigRegister(
            ppcidevice, C8XX_CONFIG_REG_IOB);
         ppcidevice->io_base = (config & 0xFFFFFFFEL);

         // get SCRIPTS RAM base address
         ppcidevice->ram_base = PCI_GetConfigRegister(
            ppcidevice, C8XX_CONFIG_REG_RAMB);

         // get ROM base address
         ppcidevice->rom_base = PCI_GetConfigRegister(
            ppcidevice, PCI_CONFIG_REG_ROM);

         // get interrupt number
         config = PCI_GetConfigRegister(
            ppcidevice, PCI_CONFIG_REG_INTL);
         ppcidevice->intl = (BYTE) config;

         retval = 1;
      }
   }

   return retval;
}



/*--------------------------------------------------*/
/*                                                  */
/* Routine to read PCI configuration register.      */
/*                                                  */
/* Usage:   DWORD PCI_GetConfigRegister(            */
/*    pci_device *ppcidevice, WORD offset)          */
/*                                                  */
/* Parameters:                                      */
/*    ppcidevice:    pointer to pci_device struct   */
/*    offset:        config register offset         */
/*                                                  */
/* Return value:                                    */
/*    Returns register value on success,            */
/*    0 otherwise.                                  */
/*                                                  */
/*--------------------------------------------------*/

DWORD PCI_GetConfigRegister(pci_device *ppcidevice,
   WORD offset)
{
   WORD r_ax, r_bx, r_di, r_dx, r_cx;
   DWORD r_ecx;
   WORD pci_version;
   DWORD retval = 0L;


   // get PCI version
   pci_version = PCI_GetPCIBIOSVersion(NULL);

   if (!(pci_version == PCI_NO_BIOS ||
      pci_version == PCI_UNKNOWN_BIOS)) {
   // PCI BIOS present

      // call PCI function to read register
      r_ax = ((PCI_FUNCTION_ID << 8) |
         (PCI_READ_CONFIG_DWORD));

      // set bus number and device number
      r_bx = ((ppcidevice->bus_num & 0xff) << 8) |
         (ppcidevice->dev_num & 0xff);

      // set configuration register offset
      r_di = offset;

      asm {
         .386
         mov ax, [r_ax]
         mov bx, [r_bx]
         mov di, [r_di]
         int PCI_BIOS_INT
         mov DWORD PTR [r_ecx], ecx
         mov [r_dx], dx
         mov [r_cx], cx
      }

      if (pci_version == PCI_BIOS_REV_1X) {
      // PCI version 1.x
         retval = r_dx;
         retval = (retval << 16) | r_cx;
      }
      else if (pci_version == PCI_BIOS_REV_2X) {
      // PCI version 2.x
         retval = r_ecx;
      }
   }

   return retval;
}



/*--------------------------------------------------*/
/*                                                  */
/* Routine to write to PCI configuration register.  */
/*                                                  */
/* Usage:   void PCI_SetConfigRegister(             */
/*    pci_device *ppcidevice, WORD offset,          */
/*    DWORD value)                                  */
/*                                                  */
/* Parameters:                                      */
/*    ppcidevice:    pointer to pci_device struct   */
/*    offset:        config register offset         */
/*    value:         value to write to register     */
/*                                                  */
/* Return value:                                    */
/*    Returns 0 if no PCI BIOS, 1 otherwise.        */
/*                                                  */
/*--------------------------------------------------*/

WORD PCI_SetConfigRegister(pci_device *ppcidevice,
   WORD offset, DWORD value)
{
   WORD r_ax, r_bx, r_di, r_dx, r_cx;
   DWORD r_ecx;
   WORD pci_version;
   WORD retval = 0;


   // get PCI version
   pci_version = PCI_GetPCIBIOSVersion(NULL);

   if (!(pci_version == PCI_NO_BIOS ||
      pci_version == PCI_UNKNOWN_BIOS)) {
   // PCI BIOS present

      retval = 1;

      // call PCI function to write to register
      r_ax = ((PCI_FUNCTION_ID << 8) |
         (PCI_WRITE_CONFIG_DWORD));

      // set bus number and device number
      r_bx = ((ppcidevice->bus_num & 0xff) << 8) |
         (ppcidevice->dev_num & 0xff);

      // set configuration register offset
      r_di = offset;

      if (pci_version == PCI_BIOS_REV_1X) {
      // PCI version 1.x
         r_cx = (WORD) value;
         r_dx = (WORD) (value >> 16);
      }
      else if (pci_version == PCI_BIOS_REV_2X) {
      // PCI version 2.x
         r_ecx = value;
      }

      asm {
         .386
         mov ax, [r_ax]
         mov bx, [r_bx]
         mov cx, [r_cx]
         mov dx, [r_dx]
         mov di, [r_di]
         mov ecx, DWORD PTR [r_ecx]
         int PCI_BIOS_INT
      }
   }

   return retval;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -